2021년 11월 16일
Kotlin 1.6.0는 이제 공식적으로 출시되었으며 안정적인 exhaustive whens, Kover, 그리고 Kotlin/Native용 새로운 메모리 매니저가 포함되었습니다. 또한 1.5.30에서 출시된 다른 언어 및 표준 라이브러리 기능들도 안정화되었습니다. 공유해 주신 피드백에 감사드립니다. 이러한 새로운 기능들을 아직 시도해보지 않았다면, 지금이 기회입니다!
이 블로그 포스트에서는 다음과 같은 업데이트 내용을 찾아볼 수 있습니다:
- sealed when 문, 중단 함수 및 중단 변환, 주석 클래스의 인스턴스화, 향상된 정규 형식 추론 및 빌더 형식 추론을 갖는 언어 기능.
- 최적화된 위임된 프로퍼티와 반복 가능한 어노테이션을 갖는 Kotlin/JVM.
- 새로운 메모리 모델 미리보기, Xcode 13 지원, Windows 대상의 크로스 컴파일, LLVM 및 링커 업데이트, 성능 업데이트 및 통합 컴파일러 플러그인 ABI를 갖는 Kotlin/Native.
- Kotlin/JS용 Node.js 및 Yarn 다운로드 비활성화 옵션.
- Kover 발표.
- 표준 라이브러리에 표준 입력을 위한 새로운 함수, Stable typeOf(), Stable Duration API 및 기타 안정화된 stdlib 함수가 포함되어 있습니다.
저희 블로그를 구독하여 Kotlin 업데이트를 놓치지 마세요.
업데이트하는 방법
IntelliJ IDEA 또는 Android Studio를 사용하는 경우 Kotlin 새 릴리스가 사용 가능해질 때 자동으로 업데이트할 수 있는 옵션이 있습니다.
Kotlin 1.6.0 설치에 대한 자세한 내용은 여기에서 확인하세요.
언어 기능
당신의 피드백을 기반으로 Kotlin 1.5.30에서 안정화된 기능들을 안내합니다.
Sealed (exhaustive) when 문
Sealed when은 기다려왔던 기능으로, Kotlin 컴파일러가 when 문이 완전하지 않을 때 경고를 표시하게 만듭니다. 이를 통해 코드를 더 안전하게 만들 수 있으며 자체 함수를 도입하지 않아도 됩니다.
Kotlin은 항상 sealed 클래스, 열거형 및 불리언 타입에 대한 when 식을 확인하여 완전성을 유지해왔습니다. 이것은 대수적 데이터 유형으로 도메인을 모델링할 때 유용합니다. 예를 들어 앱 사용자의 다른 연락처 기본 설정을 sealed 클래스 계층 구조로 모델링할 수 있습니다:
sealed class Contact {
data class PhoneCall(val number: String) : Contact()
data class TextMessage(val number: String) : Contact()
data class InstantMessage(val type: IMType, val user: String) : Contact()
}
이제 다른 연락처 기본 설정에 따라 다른 결과를 반환하는 표현식을 작성하면, 컴파일러는 앱에 있는 모든 유형을 처리하는 것을 잊었을 때 오류를 표시합니다:
fun Rates.computeMessageCost(contact: Contact): Cost =
when (contact) { // ERROR: 'when' expression must be exhaustive
is Contact.PhoneCall -> phoneCallCost
is Contact.TextMessage -> textMessageCost
}
이것은 코드 작성 및 미래 유지 관리 모두에 큰 도움이 됩니다. 나중에 다른 종류의 연락처 기본 설정을 추가하면 컴파일러가 코드 주변에 다른 종류의 연락처 기본 설정을 처리하지 않았는지 잊지 않도록 확인합니다.
그러나 Kotlin 1.6 이전에는 다음과 같이 when 문을 사용하는 이 코드가 성공적으로 컴파일되지만, 즉각 메시지를 통해 사용자에게 발표물을 보내는 것을 처리하는 것을 완전히 잊어버립니다:
fun sendAnnouncement(contact: Contact, announcement: Announcement) {
when (contact) {
is Contact.PhoneCall -> schedulePhoneCall(contact.number, announcement)
is Contact.TextMessage -> sendTextMessage(contact.number, announcement)
}
}
컴파일러에서는 메시지 없이 약한 IDE 검사만 보고됩니다. 그러나 Kotlin 1.6부터는 다음과 같은 컴파일러 경고가 표시됩니다:
Sealed 클래스/인터페이스에서 완전하지 않은 'when' 문은 1.7에서 금지됩니다. 'is InstantMessage' 분기 또는 'else' 분기를 추가하십시오.
Kotlin 1.7에서는 오류가 발생하여 실수로 놓치는 기회가 없을 것입니다. 변경 내용과 그 영향에 대한 자세한 설명은 KT-47709를 참조하세요.
서스펜딩 함수를 슈퍼 타입으로 사용하기
Kotlin 1.6은 서스펜딩 기능형 타입을 슈퍼 인터페이스로 구현하는 지원을 안정화했습니다. 이것은 Kotlin 코루틴 디자인에서 빠져있던 부분 중 하나였습니다.
Kotlin API를 설계할 때 라이브러리 함수의 동작을 사용자 정의해야 할 때 함수형 타입을 받는 것이 관용적입니다. 예를 들어 kotlinx.coroutines API에는 다음과 유사한 Job 인터페이스의 멤버 함수가 있습니다:
fun invokeOnCompletion(handler: () -> Unit)
이 함수는 invokeOnCompletion { doSomething() }와 같은 람다와 편리하게 사용할 수 있습니다. 만약 클래스로 완료 처리를 다루고 싶다면, 추가적인 람다를 생성하지 않고 클래스 내에서 직접 () -> Unit와 같은 함수형 타입을 구현하여 코드를 더 간소화하고 최적화할 수 있습니다:
class MyCompletionHandler : () -> Unit {
override fun invoke() { doSomething() }
}
Kotlin 1.6부터는 이러한 최적화가 서스펜딩 함수에도 가능합니다. 만약 API가 이와 같이 서스펜딩 함수형 타입을 받는다면:
public fun launchOnClick(action: suspend () -> Unit) {}
이제 람다와 서스펜딩 함수 참조만 이 코드에 전달하는 것에 제한되지 않습니다. 클래스 내에서도 해당 서스펜딩 함수형 타입을 구현할 수 있습니다:
class MyClickAction : suspend () -> Unit {
override suspend fun invoke() { doSomething() }
}
서스펜딩 변환
Kotlin 1.6은 일반 함수형 타입에서 서스펜딩 함수형 타입으로의 변환을 안정화합니다. 이제 적절한 일반 함수형 타입의 표현식을 파라미터로 사용하는 곳에서 서스펜딩이 필요한 경우 자동으로 변환을 수행합니다.
이것은 Kotlin에서 일반 함수와 서스펜딩 함수 간 상호작용의 작은 불일치를 해결합니다. Kotlin Flow에서 수집 호출과 같이 서스펜딩 함수를 받는 고차 함수가 있다면, 다음과 같이 호출하기 위해 람다를 사용하는 대신:
flow.collect { processItem(it) }
fun processItem(item: Item) { /* ... */ }
flow.collect(::processItem)와 같이 processItem 함수에 대한 참조를 collect 호출에 전달하는 것이 편리할 수 있습니다. 그러나 이것은 Kotlin 1.6 이전 버전에서 작동하지 않았습니다. 이는 일반 함수를 서스펜딩 타입의 파라미터로 전달하고 있기 때
문입니다:
val processingFunction = ::processItem
flow.collect(processingFunction) // ERROR: Type mismatch
Kotlin 1.6에서는 위의 코드가 컴파일되며 작동합니다.
재귀 제네릭 타입의 개선된 타입 추론
1.6.0부터 Kotlin 컴파일러는 재귀 제네릭 타입의 경우 해당 타입 파라미터의 상한만을 기반으로 타입 인자를 추론할 수 있습니다. 이것은 빌더 API를 만들 때 자주 사용되는 Java에서 사용되는 재귀 제네릭 타입과 관련된 다양한 패턴을 만들 수 있게 합니다.
// 1.5.30 이전
val containerA = PostgreSQLContainer<nothing>(DockerImageName.parse("postgres:13-alpine")).apply {
withDatabaseName("db")
withUsername("user")
withPassword("password")
withInitScript("sql/schema.sql")
}
// 1.5.30의 컴파일러 옵션 또는 1.6.0부터는 기본값으로
val containerB = PostgreSQLContainer(DockerImageName.parse("postgres:13-alpine"))
.withDatabaseName("db")
.withUsername("user")
.withPassword("password")
.withInitScript("sql/schema.sql")
빌더 추론 개선
Kotlin 1.5.30에서는 -Xunrestricted-builder-inference 컴파일러 옵션을 도입하여 빌더 호출에 대한 유형 정보를 빌더 람다 내에서 사용 가능하게 했습니다. 구체적으로, 빌더 람다 내에서 get()과 같은 아직 추론되지 않은 유형의 인스턴스를 반환하는 호출을 만들 수 있도록 했습니다.
1.6.0부터는 이전에 금지되었던 호출을 지정할 때 -Xunrestricted-builder-inference를 지정할 필요가 없습니다. -Xenable-builder-inference 컴파일러 옵션을 사용하여 일반 유형 추론이 유형 정보를 해결하지 못할 경우 자동으로 빌더 추론을 활성화할 수 있습니다.
이전 API 버전 지원 연장
Kotlin 1.6.0부터는 현재 안정 버전과 함께 두 개가 아닌 세 개의 이전 API 버전을 사용하여 개발할 수 있습니다. 현재로서는 API 버전 1.3, 1.4, 1.5 및 1.6이 포함됩니다. 이것은 이전 버전과의 호환성을 유지하면서 새로운 기능을 도입하는 데 도움이 될 수 있습니다.
Kotlin/JVM
실행시 유지 가능한 반복 어노테이션. Kotlin은 Java 8과 같이 반복 어노테이션을 지원합니다. Kotlin 1.6에서는 이 기능이 Java와 호환되며 @kotlin.annotation.Repeatable이 모든 유지를 허용하고 Kotlin 및 Java에서 어노테이션을 반복 가능하게 만듭니다. 또한 Kotlin 측에서도 Java 반복 어노테이션을 지원합니다.
Kotlin/Native
이제 새로운 Kotlin/Native 메모리 매니저의 실험 버전을 시도할 수 있습니다. 이 기능을 통해 멀티플랫폼 프로젝트에서 일관된 개발자 경험을 제공하는 방향으로 나아가고 있습니다. 이 새로운 메모리 매니저는 스레드 간 객체 공유에 대한 기존 제약을 제거하고 개발자로부터 특별한 관리나 어노테이션을 필요로 하지 않는 완전히 누수가 없는 동시 프로그래밍 원시 기능을 제공합니다.
Xcode 13을 지원하는 Kotlin/Native. 이제 Kotlin/Native는 Xcode 13을 지원하므로 Xcode를 자유롭게 업데이트하고 Kotlin 프로젝트에서 작업을 계속할 수 있습니다.
모든 호스트에서 Windows 대상 컴파일. Kotlin/Native를 지원하는 모든 호스트에서 Windows 대상 mingwX64 및 mingwX86를 컴파일할 수 있습니다.
Kotlin/Native가 내부적으로 사용하는 LLVM 종속성을 다시 작성했습니다. 이로 인해 11.1.0으로 업데이트된 LLVM 버전과 종속성 크기가 줄어들었습니다.
JVM 및 JS IR 백엔드와 통합된 통일된 컴파일러 플러그인 ABI. 이제 Kotlin Multiplatform Gradle 플러그인은 Kotlin/Native을 위해 사용되는 것과 같은 JVM 및 JS IR 백엔드에 사용되는 중첩 컴파일러 jar를 사용할 수 있습니다. 이제 Native 및 다른 지원되는 플랫폼에 대한 동일한 컴파일러 플러그인 아티팩트를 사용할 수 있습니다.
Kotlin/JS
인터넷 연결 없이 서버에서 빌드할 때, 이제 Kotlin/JS 프로젝트에서 Node.js 및 Yarn 다운로드를 비활성화하고 호스트에 이미 설치된 인스턴스를 사용할 수 있습니다.
Kover
첫 번째 릴리스 이후로 코드 커버리지의 정확한 측정은 어려움이었습니다. JaCoCo와 같은 훌륭한 도구들은 Kotlin 코드와 작동하지만 Gradle 도구 체인 및 멀티플랫폼 프로젝트와 완전히 통합되지 않았습니다. 이 Kotlin 릴리스에서는 이 문제를 해결하기 시작했습니다. Kover는 Kotlin/JVM 컴파일러로 빌드된 Kotlin 코드에 대한 코드 커버리지를 측정하는 새로운 Gradle 플러그인입니다. 현재 이 플러그인은 초기 개발 단계에 있으며 실험적입니다. GitHub에서의 피드백을 환영합니다. Kover 비디오를 시청하여 더 자세한 내용을 확인하세요.
표준 라이브러리
Kotlin 1.6.0은 세 가지 stdlib 로드맵 항목을 완료하여 readLine() 후에 !!를 제거하고 typeOf()를 안정화하며 안정적인 Duration API를 제공합니다. 또한 다음 stdlib 함수를 Stable로 승격합니다:
- 컬렉션 빌더
- 정수에 대한 비트 회전 연산
- 문자열을 시퀀스로 분할하기 위한 정규식 함수
또한 Comparable.compareTo를 인픽스 표기법으로 호출하는 기능을 추가하고 JVM과 JS에서 replace() 함수를 사용할 때 일관된 경험을 제공하기 위해 투자했습니다.
새로운 표준 입력 함수
Kotlin 1.6.0에서 새로운 표준 입력 함수를 제공하여 안전성을 향상시키고 Kotlin을 배우는 사람들에게 더 간단한 경험을 제공합니다.
- readln(): 이 함수는 EOF(End of File)에 도달하면 예외를 throw합니다. 이제 readLine() 결과를 !! 연산자로 null 체크하는 대신 이 함수를 사용할 수 있습니다.
- 새로운 이름을 가진 readlnOrNull()도 있으며, 이 함수는 이전의 readLine()과 동일하게 동작하지만 이름이 더 표현적입니다.
이러한 함수는 이제 JVM과 Native 플랫폼에서 사용 가능하며, 이 함수들의 네이밍 컨벤션은 특히 초보자에게 중요한 println()과 일치하도록 변경되었습니다.
fun main() {
println("두 개의 정수 숫자를 각각 다른 줄에 입력하세요")
val num1 = readln().toInt()
val num2 = readln().toInt()
println("$num1와 $num2의 합은 ${num1 + num2}입니다.")
}
안정된 Duration API
귀하의 피드백 덕분에 Duration API를 안정화하고 해당 로드맵 항목을 닫았습니다.
1.5.30에서 미리보기로 사용 가능한 Duration.toString()의 더 가독성 있는 출력과 문자열에서 Duration을 구문 분석하는 새로운 함수 외에도 Duration API에는 다음과 같은 변경 사항이 있었습니다:
- toComponents 함수의 days 구성 요소는 값이 잘려나가지 않도록 Int 대신 Long 유형을 사용하도록 변경되었습니다.
- DurationUnit 열거형은 이제 유형 별칭이 아닙니다. JVM에서는 java.util.concurrent.TimeUnit의 유형 별칭으로 사용되지 않습니다.
- 커뮤니티 피드백에 대응하여 Int.seconds와 같은 확장 속성을 다시 도입하고, 그 적용 범위를 제한하기 위해 이제 Duration 클래스의 Companion에서만 사용할 수 있습니다.
val duration = 5000.seconds
println("There are ${duration.inWholeMinutes} minutes in ${duration.inWholeHours} hours")
안정적인 typeOf()
Kotlin 1.6.0에서는 안정적인 typeOf()을 도입하며 해당 로드맵 항목을 종료합니다. 1.3.40부터 typeOf()는 실험적인 API로 JVM 플랫폼에서 사용 가능했으며 이제는 모든 Kotlin 플랫폼에서 사용할 수 있으며 컴파일러가 추론할 수 있는 모든 Kotlin 타입의 KType 표현을 얻을 수 있습니다.
inline fun <reified T> renderType(): String {
val type = typeOf<T>()
return type.toString()
}
fun main() {
val fromExplicitType = typeOf<Int>()
val fromReifiedType = renderType<List<Int>>()
}
안정적인 컬렉션 빌더
Kotlin 1.6.0에서는 컬렉션 빌더 함수인 buildMap(), buildList(), 그리고 buildSet()을 안정 버전으로 승격합니다. 빌더에서 반환된 컬렉션은 이제 읽기 전용 상태에서 직렬화될 수 있습니다.
안정적인 정수용 비트 회전 연산
Kotlin 1.6.0에서는 숫자의 이진 표현을 지정된 비트 수만큼 왼쪽 또는 오른쪽으로 회전시키는 rotateLeft() 및 rotateRight() 함수가 안정 버전으로 변경되었습니다.
val number: Short = 0b10001
println(number.rotateRight(2).toString(radix = 2)) // 100000000000100
println(number.rotateLeft(2).toString(radix = 2)) // 1000100
안정적인 정규식 함수로 문자열을 시퀀스로 분할
Kotlin 1.6.0에서는 문자열을 시퀀스로 분할하는 정규식 함수인 splitToSequence()도 안정화되었습니다.
val colorsText = "green, red , brown&blue, orange, pink&green"
val regex = "[,\\s]+".toRegex()
val mixedColor = regex.splitToSequence(colorsText)
.onEach { println(it) }
.firstOrNull { it.contains('&') }
println(mixedColor) // "brown&blue"
중위 표기법으로 compareTo 호출 추가
두 개의 객체를 비교하기 위해 Comparable.compareTo 함수를 중위 표기법으로 호출할 수 있는 기능이 추가되었습니다:
class WrappedText(val text: String) : Comparable<WrappedText> {
override fun compareTo(other: WrappedText): Int =
this.text compareTo other.text
}
일관된 replace() 및 replaceFirst() (JVM 및 JS)
Kotlin 1.6.0 이전에, replace() 및 replaceFirst() 정규식 함수는 대체 문자열이 그룹 참조를 포함하는 경우 JVM 및 JS에서 다르게 동작했습니다. Kotlin/JS에서의 동작이 이제 JVM과 일관되도록 변경되었습니다.
호환성
모든 기능 업데이트와 마찬가지로, Kotlin 1.6.0에서 이전에 발표된 변경 사항의 일부 사용 중단 주기가 마감됩니다. 이러한 모든 경우는 언어 위원회에서 주의 깊게 검토했으며 Kotlin 1.6.0의 호환성 가이드에 나열되어 있습니다. 이 변경 사항은 YouTrack에서도 확인할 수 있습니다.
Kotlin 1.6.0 설치 방법
IntelliJ IDEA 또는 Android Studio를 사용하는 경우 IDE에서 Kotlin을 자동으로 1.6.0으로 업데이트하도록 제안합니다. 또는 다음 지침을 따라 수동으로 업데이트할 수 있습니다.
Kotlin에 대한 광범위한 지원을 얻기 위해 이 IDE들의 최신 버전을 다운로드하세요:
- IntelliJ IDEA - 다양한 플랫폼용 Kotlin 애플리케이션 개발.
- Android Studio - Android 및 크로스 플랫폼 모바일 애플리케이션 개발.
또한 호환 버전의 kotlinx 라이브러리를 업데이트하고 기존 프로젝트의 빌드 스크립트에 Kotlin 1.6.0을 지정했는지 확인하세요.
명령줄 컴파일러가 필요한 경우 Github 릴리스 페이지에서 다운로드하세요.
문제가 발생하면:
- Slack에서 도움을 찾으세요 (초대를 받으세요).
- 이슈 트래커 YouTrack에 문제를 신고하세요.
최신 Kotlin 기능을 최신 상태로 유지하세요! 이 게시물 오른쪽에 있는 양식을 작성하여 Kotlin 업데이트를 받으세요.
무엇을 더 읽고 시청해야 할까요
- Kotlin 로드맵
- Kover - 코드 커버리지 플러그인
- Kotlin 1.6.0 문서에서의 새로운 내용
- YouTube에서 Kotlin 1.6.0의 새로운 내용
- Kotlin 1.6을 위한 호환성 가이드
- Kotlin 1.5.30이 이제 사용 가능합니다!
YouTrack의 최고 이슈 제보자
Ryan Nett (48 건), Zac Sweers (22 건), Tianyu Geng (18 건), zhelenskiy (18 건), Thodoris Sotiropoulos (15 건), AndroidDeveloperLB (14 건), Morgan, Bartholomew (14 건), Mikhail Naftal (14 건), Louis CAD (12 건), Philip Wedemann (12 건), Victor Turansky (11 건), Igor Wojda (11 건), Martin Bonnin (11 건), Iaroslav Postovalov (11 건), Cedric (10 건), 凛 (9 건), Ben Woodworth (8 건), Tianyi Guan (8 건), Chris Povirk (8 건), Alon Albert (8 건).
외부 기여자
이 릴리스에 포함된 모든 기여자에게 감사의 인사를 드립니다: Pyos, Tianyu Geng, Jinseong Jeon, Steven Schäfer, Mark Punzalan, Hung Nguyen, Mads Ager, Ting-Yuan Huang, Matthew Gharrity, Ivan Gavrilovic, Xin Wang, ov7a, Jiaxiang Chen, Yigit Boyar, Bingran, bracadabra, Steffi Stumpos, Andrey Kuleshov.
원문
https://blog.jetbrains.com/kotlin/2021/11/kotlin-1-6-0-is-released/
댓글