코틀린 1.4.30에서 새롭게 추가된 것들
코틀린 1.4.30에서는 새로운 기능에 대한 preview를 제공합니다. 코틀린/JVM 컴파일러의 새로운 IR 백엔드는 알파단계로 올라갔고, 다양한 성능, 기술적인 개선사항들이 있습니다.
언어적 특징
코틀린 1.5.0에서는 새로운 언어적 기능을 제공할 예정입니다. JVM record 지원, sealed 인터페이스, 안정적인 inline 클래스들 등이 있습니다. 코틀린 1.4.30에서는 이러한 기능 및 개선들을 preview 모드로 사용해볼 수 있습니다.
YouTrack 티켓으로 피드백을 전달해주면 감사드리겠습니다. 그리고 1.5.0 릴리즈 이전에 반영해두겠습니다.
- JVM records 지원
- sealed 인터페이스와 sealed 클래스 개선사항
- inline 클래스들 개선
1. JVM records 지원
이 기능은 Experimental 하고, 언제든지 변경되고 없어질 수 있습니다.
JDK 16에서는 새로운 자바 클래스 타입인 record를 안정적으로 포함하는걸 목표하고 있습니다. 코틀린의 혜택들을 그대로 제공하고 자바와의 호환성을 유지하기 위해서 코틀린에서는 record 클래스 지원을 experimental로 제공합니다.
자바에서 선언한 record 클래스들을 코틀린에서 다른 클래스들과 같이 프로퍼티와 사용가능합니다. 다른 추가적인 무언가를 하지 않아도 됩니다.
1.4.30에서 시작하기 위해서는 코틀린에서 선언한 record 클래스에 @JvmRecord를 달아주면 됩니다.
@JvmRecord
data class User(val name: String, val age: Int)
JVM record의 preview 버전을 사용하고 싶다면, 컴파일러 옵션에 -Xjvm-enable-preview와 -language-version 1.5를 추가하시면 됩니다.
2. Sealed interface
이 기능은 experimental 합니다. 언제든지 변경되고 없어질 수 있습니다.
코틀린 1.4.30에서 sealed 인터페이스의 프로토타입이 추가되었습니다. sealed 인터페이스는 sealed 클래스를 보완하고, 클래스 계층구조의 제약 없이 더 유연하게 사용 가능합니다.
sealed 인터페이스는 같은 모듈 외부에서 implemented될 수 없는 "internal" 인터페이스로 선언 가능합니다. 이런 사실에 기반하여 아래 코드처럼 when절을 작성할 수 있습니다.
sealed interface Polygon
class Rectangle(): Polygon
class Triangle(): Polygon
// when() is exhaustive: no other polygon implementations can appear
// after the module is compiled
fun draw(polygon: Polygon) = when (polygon) {
is Rectangle -> // ...
is Triangle -> // ...
}
다른 사용 케이스 : sealed 인터페이스를 통하여, 두 개 이상의 sealed 수퍼 클래스를 상속받을 수 있습니다.
sealed interface Fillable {
fun fill()
}
sealed interface Polygon {
val vertices: List<Point>
}
class Rectangle(override val vertices: List<Point>): Fillable, Polygon {
override fun fill() { /*...*/ }
}
sealed 인터페이스의 preview 버전을 사용하고 싶다면, 컴파일러 옵션으로 -language-version 1.5를 추가하면 됩니다.
3. 패키지 범위의 sealed 클래스 계층구조
이 기능은 experimental 합니다. 언제든지 변경되고 없어질 수 있습니다.
이제 sealed 클래스들은 더 유연한 계층구조를 가질 수 있게 되었습니다. 같은 compilation 유닛 및 같은 패키지 내부의 모든 파일들의 서브클래스들을 가질 수 있게 되었습니다. 이전에는 같은 파일에 있는 서브클래스들만 사용 가능했습니다.
직접적인 서브클래스들은 탑레벨일수도 있고, 다른 네임드 클래스, 인터페이스, 객체의 nested 될 수도 있습니다. sealed 클래스의 서브클래스들은 적절한 이름을 반드시 가지고 있어야 합니다.
4. inline 클래스 개선사항
이 기능은 experimental 합니다. 언제든지 변경되고 없어질 수 있습니다.
코틀린 14.30에서 inline 클래스는 베타 버전이 되었고, 아래와 같은 개선사항들이 있었습니다.
- inline 클래스들이 value-based이기 때문에 value modifier를 사용하여 정의할 수 있습니다. inline, value modifier는 서로 동일합니다. 미래 코틀린 버전에서는 inline modifier를 deprecate 할 예정입니다.
지금부터, 코틀린 JVM 백엔드에서는 클래스 어노테이션에 @JvmInline을 필요로 합니다.
inline class Name(private val s: String) value class Name(private val s: String) // For JVM backends @JvmInline value class Name(private val s: String)
- inline 클래스들은 init 블록을 가질 수 있습니다. 클래스 인스턴스화 이후에 실행될 코드를 추가할 수 있습니다.
@JvmInline value class Negative(val x: Int) { init { require(x < 0) { } } }
- 자바 코드에서 inline 클래스들 호출:: 코틀린 1.4.30 전에는, 자바에서 inline 클래스를 파라미터로 가지고 있는 함수를 호출할 수 없었습니다. 하지만 지금부터, @JvmName 어노테이션을 함수 선언에 추가하면 함수를 자바코드에서 호출할 수 있습니다.
inline class UInt(val x: Int) fun compute(x: Int) { } @JvmName("computeUInt") fun compute(x: UInt) { }
코틀린/JVM
JVM IR 컴파일러 백엔드가 베타 버전에 도달하였습니다.
1.4.0에서 알파 단계였던, 코틀린/JVM의 IR 기반 컴파일러가 베타 단계에 돌입하였습니다. 이번이 코틀린/JVM 컴파일러로 IR 백엔드가 default가 되기전 마지막 pre-stable 레벨입니다.
우리는 IR 컴파일러로부터 생산되는 바이너리들을 소비하는 것에 대한 제약을 제거하였습니다. 이전에는, 새로운 백엔드를 활성화 할 경우에만 새로운 JVM IR 백엔드로부터 컴파일 되는 코드를 사용할 수 있었습니다. 1.4.30부터는, 이러한 제약이 없기 때문에, 라이브러리 같은 서드 파티를 사용하여 컴포넌트를 빌드할 때도 새로운 백엔드를 사용할 수 있습니다.
새로운 JVM IR 백엔드를 활성화 하기 위해서는 아래와 같은 설정이 필요합니다.
Gradle
tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile::class) {
kotlinOptions.useIR = true
}
Maven
<configuration>
<args>
<arg>-Xuse-ir</arg>
</args>
</configuration>
Copied!
표준 라이브러리
위치에 구분되지 않는 upper/lowercasing text api
이 api는 experimental합니다. 언제든지 변경되고 없어질 수 있습니다.
이번 릴리즈에서는 string과 character에 쓰이고, 위치에 구분되지 않는 experimental 한 변경 API 가 추가되었습니다. 현재 toLowerCase(), toUpperCase(), capitalize(), decapitalize() API 함수들은 위치에 영향을 받습니다. 이 의미는 위치 셋팅값에 따라서 결과가 달라진다는 의미입니다. 예를 들어서 Turkish 지역에서는 "kotlin"을 toUpperCase로 변환하면 결과가 "KOTLIN"이 아니라
"KOTLİN" 으로 나옵니다 ( 대문자 I 위에 점 하나 더 )
// current API
println("Needs to be capitalized".toUpperCase()) // NEEDS TO BE CAPITALIZED
// new API
println("Needs to be capitalized".uppercase()) // NEEDS TO BE CAPITALIZED
코틀린 1.4.30은 아래와 같은 대안을 제시합니다.
- String
- Char
코틀린/JVM에서는 명시적인 Locale 파라미터와 함께 uppercase(), lowercase(), titlecase() 함수들이 오버로딩 됩니다.
명확한 Char to code, Char to digit 변환
이 api 는 experimental 합니다. 언제든지 변경되거나 없어질 수 있습니다.
다른 숫자 타입에서 UTF-16 코드로 표현되는 것을 돌려주는 현재의 Char to Number 변환 함수는 종종 비슷한 String to Int 변환과 혼동됩니다.
"4".toInt() // returns 4
'4'.toInt() // returns 52
// and there was no common function that would return the numeric value 4 for Char '4'
이러한 혼동을 피하기 위해서, 우리는 Char 변환을 아래 두개의 명확하게 이름지어진 함수들로 분리하기로 결정하였습니다.
- Char의 Integer 코드를 돌려주는 함수, 주어진 code로 Char를 생성하는 함수
fun Char(code: Int): Char fun Char(code: UShort): Char val Char.code: Int
- Char를 나타내는 숫자값으로 변환해주는 함수
fun Char.digitToInt(radix: Int): Int fun Char.digitToIntOrNull(radix: Int): Int?
- Int의 확장함수로, 양수를 표현하는 Char 로 변경시켜주는 함수
fun Int.digitToChar(radix: Int): Char
Serialization 업데이트
코틀린 1.4.30에서, 몇가지 기능을 포함한 kotlinx.serialization 1.1.0-RC를 릴리즈 했습니다.
- inline 클래스 serialization 지원
- unsigned 프리미티브 타입 serialization 지원
inline 클래스 serialization 지원
코틀린 1.4.30부터, inline 클래스 serializable이 가능해졌습니다.
@Serializable
inline class Color(val rgb: Int)
이 기능은 새로운 1.4.30 IR 컴파일러를 필요로 합니다.
unsigned 프리미티브 타입 serialization 지원
1.4.30부터, unsigned 프리미티브 타입 UInt, ULong, UByte, UShort에 kotlinx.serialization의 표준 JSON serializer를 사용할 수 있습니다.
@Serializable
class Counter(val counted: UByte, val description: String)
fun main() {
val counted = 239.toUByte()
println(Json.encodeToString(Counter(counted, "tries")))
}
출처
'Kotlin' 카테고리의 다른 글
코틀린 1.4, 1.5 버전에서의 변경사항 (0) | 2021.08.15 |
---|---|
(번역글) kotlin 1.5.20 릴리즈 노트 (0) | 2021.08.15 |
(번역글) 코틀린 1.5.0 버전 릴리즈 노트 (0) | 2021.08.14 |
(번역글) 코틀린 1.4.20 버전 릴리즈 노트 (0) | 2021.08.11 |
(번역글) 코틀린 1.4.0 버전 변경 사항 (0) | 2021.07.24 |