Kotlin 언어의 버전을 올릴 때는 사용하는 IntelliJ 버전도 함께 확인해야 한다.
IntelliJ 버전마다 지원되는 Kotlin 버전이 따로 있기 때문이다.
2025년 6월 23일 Kotlin 2.2.0 이 출시 되었다. 언어 레벨에서 알아두면 좋을만한 것만 빠르게 정리해보자.
1. non-local break / continue
Kotlin에는 non-local return 이라는 개념이 있다.
관련 강의 : <코틀린 고급편 - 15강. inline 함수 자세히 살펴보기>
fun execution() {
iterate(listOf(1, 2, 3)) {
if (it == 2) {
// 람다 안에 return이 들어 있다. 이게 바로 non-local return
return
}
println(it)
}
}
fun iterate(numbers: List<Int>, exec: (Int) -> Unit) {
for (number in numbers) {
exec(number)
}
}
Kotlin
복사
위 코드 예시에서 iterate 함수가 일반 함수이면, return 을 사용할 수 없고, inline 이면 컴파일 단에서 함수가 인라인닝 되므로 return을 사용할 수 있었다.
물론 이때 return 이 가리키는 fun 은 눈에 보이는 것처럼 return 바로 위에 execution 이 된다.
그런데 continue 혹은 break 는 인라이닝 된 상황에서도 아예 사용할 수 없었다. 그래서 다음과 같은 낯선 라벨 (@) 을 사용해야 했다.
fun execution() {
listOf(1, 2, 3).forEach { // forEach 역시 inline 함수이다.
if (it == 2) {
return@forEach // 사실상 continue
}
println(it)
}
}
Kotlin
복사
…
여기까지 들으면 마치 non-local break 와 non-local continue 가 가능해지며 다음 코드가 실행되는 것처럼 보인다.
fun execution() {
listOf(1, 2, 3).forEach { // forEach 역시 inline 함수이다.
if (it == 2) {
continue // 드디어 여기서 continue를 쓸 수 있게 되는것인가!!!
}
println(it)
}
}
Kotlin
복사
하지만 그렇지는 않다.
inline 안에서 return 키워드를 사용했지만 진정한 의미는 코드 흐름상 가장 가까운 fun 에 대한 반환이었던 것처럼,
continue 와 break 는
•
전통적인 for (.. in ..) 안에서만 사용 가능하고
•
inline 안에 있는 continue 와 break 도 코드 흐름상 가장 가까운 for (.. in ..) 에 대해 동작하게 된다.
따라서 이번 non-local continue, break로 정말 동작하게 된 코드는
fun execution(list: List<Int>) {
for (num in list) {
run {
if (num == 2) {
continue // for (num in list) 에 대한 continue
}
}
println(num)
}
}
Kotlin
복사
위 코드처럼 전통적인 for문 안에 inline 함수 (run) 안에 있는 continue 가 예시이다.
2. Guard Condition in when with a subject
guard condition은 최근 java에도 도입된 기능이다.
when expression을 사용할 때 단순히 특정 타입인지 확인하는 것을 넘어 추가 조건 (guard condition) 도 확인할 수 있게 해준다.
sealed interface Animal
data class Cat(val name: String) : Animal
data class Dog(val name: String) : Animal
// when expression with guard condition
fun handleAnimal(animal: Animal) {
when (animal) {
// 원래 사용하던 스타일
is Cat -> "고양이 ${animal.name}"
// 타입 확인 이후 if를 이용해 한 번더 확인 가능.
// 이때 animal은 Dog 타입으로 smart cast 되어 있다.
is Dog if (animal.name == "Buddy") -> "우리 귀여운 Buddy ${animal.name}"
is Dog -> "강아지 ${animal.name}"
}
}
Kotlin
복사
3. Multi-dollar interpolation
기본적으로 Kotlin은 문자열 안의 $ 를 특수하게 인식한다.
val person = Person("태현")
println("안녕, 나는 ${person.name}이야")
Kotlin
복사
처럼 문자열 안에 변수를 넣기 위해서인데..
간혹 $를 $ 자체로 문자열에 넣어야 할 때가 있다. 스프링 @Value 가 대표적이다.
@Value("\${spring.properties}")
Kotlin
복사
그래서 이럴 때는 항상 back slash (\)를 앞에 넣어주고 그 다음 $를 표기해 $가 문자열로 처리되게끔 했는데
이제 또 다른 방법이 생겼다. 어떤 literal 앞에 $$ 를 넣으면 그 literal 안에 있는 $는 문자열로 인식하게 된다.
println($$"${spring.properties}")
Kotlin
복사
그리고 만약 $$ 기호를 사용했지만 변수도 함께 넣고 싶다면, 그 안에 $$ 를 또 다시 사용하면 된다.
val person = Person("태현")
println($$"안녕, 나는 $${person.name}이야. $는 좋아")
// 출력 결과 = 안녕, 나는 태현이야. $는 좋아
Kotlin
복사