val a = 1
fun fizz() {
val b = 2
print(a + b)
}
val buzz = {
val c = 3
print(a + c)
}
// 여기선 a를 사용할 수 있지만, b, c는 사용 불가
for ((i, user) in users.withIndex()) { // 스코프를 좁게 가져가는 좋은 예
// ...
}
if
, when
, try-catch
, Elvis
표현식 등을 활용하면 최대한 바로 초기화가 가능하다.val user: User = if (hasValue) getValue() else User()
fun updateWeather(degrees: Int) {
val (description, color) = when {
degrees < 5 -> "cold" to Color.BLUE
degrees < 23 -> "mild" to Color.YELLOW
else -> "hot" to Color.RED
}
}
var numbers = (2..100).toList()
val primes = mutableListOf<Int>
while (numbers.isNotEmpty()) {
val prime = numbers.first()
primes.add(prime)
numbers = numbers.filter { it % prime != 0 }
}
print(primes.take(10).toList()) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
generateSequence
는 Kotlin에서 지연(lazy) 시퀀스(Sequence)를 생성할 때 사용하는 함수로 이 함수 초기값(seed)과 다음 값을 계산하는 람다 함수를 인자로 받아, 각 단계마다 새로운 값을 계산하며 시퀀스를 생성한다.yield
는 코루틴 빌더인 sequence { ... }
블록 안에서 사용되어 호출되면, 그 값을 시퀸스의 다음 값으로 “내보내고”, 함수 실행을 잠시 멈췄다가, 다음 값이 필요할 때 다시 이어서 실행된다.val primes: Sequence<Int> = sequence {
val numbers = generateSequence(2) { it + 1 }
var prime: Int
while (true) {
prime = numbers.first()
yield(prime)
numbers = numbers.drop(1)
.filter { it % prime != 0 }
}
}
print(primes.take(10).toList()) // [2, 3, 5, 6, 7, 8, 9, 10, 11, 12]
prime
변수를 캡처했기 때문filter { it % prime != 0 }
람다는 prime
변수를 참조만 하고, 값을 복사하지 않는다.prime
변수는 while
루프 안에서 계속 바뀌고 있다.take(10).toList()
)에 람다 내부의 prime
은 마지막 루프에서 할당된 값만 참조하게 된다.val primes: Sequence<Int> = sequence {
val numbers = generateSequence(2) { it + 1 }
while (true) {
val prime = numbers.first()
yield(prime)
numbers = numbers.drop(1)
.filter { it % prime != 0 }
}
}