본문 바로가기
Kotlin/Release Notes

[Kotlin Release Notes] Kotlin 1.4-M1 Released

by 노력남자 2023. 9. 10.
반응형

2020년 3월 23일

 

새로운 주요 릴리스인 Kotlin 1.4-M1의 첫 번째 프리뷰 버전을 발표하게 되어 기쁩니다.

몇 달 전에 Kotlin 1.4에서 기대할 수 있는 내용을 발표한 바 있습니다. 릴리스가 점점 다가옴에 따라 여러분들에게 스스로 새로운 기능 중 일부를 시도할 수 있는 프리뷰 버전을 제공하게 되었습니다.


이 게시물에서는 1.4-M1에서 제공되는 다음과 같은 새로운 기능과 주요 개선 사항을 강조하겠습니다.

  • 새롭고 강력한 타입 추론 알고리즘이 기본값으로 활성화되었습니다.
  • 최종 멤버 함수에 대한 Contracts(계약)이 이제 사용 가능합니다.
  • Kotlin/JVM 컴파일러는 이제 Java 8+ 대상에 대한 바이트 코드에 타입 주석을 생성합니다.
  • 결과 아티팩트에 주요 개선 사항을 가져오는 Kotlin/JS의 새로운 백엔드가 추가되었습니다.
  • 표준 라이브러리의 진화적인 변화: 폐기 주기 완료 및 일부 추가 부분 폐기.

 

변경 내용의 전체 목록은 변경 로그에서 확인하실 수 있습니다. 언제나 외부 기여자분들께 큰 감사를 드립니다.

프리뷰를 시도하고, 우리의 이슈 트래커에서 제공하는 피드백을 환영하며 기대하고 있습니다.

 

더 강력한 타입 추론 알고리즘

 

Kotlin 1.4-M1에서는 더 강력한 타입 추론 알고리즘이 사용됩니다. 이전에는 Kotlin 1.3에서 컴파일러 옵션을 지정하여 이 새로운 알고리즘을 시도할 수 있었으며, 이제 기본적으로 사용됩니다. 이 새로운 알고리즘이 도입된 데에 기여한 이슈의 전체 목록은 YouTrack에서 확인할 수 있습니다. 이 블로그 게시물에서는 가장 눈에 띄는 개선 사항 중 일부를 강조하겠습니다.


Kotlin 함수와 인터페이스에 대한 SAM 변환


SAM 변환은 "단일 추상 메서드"를 가진 인터페이스가 예상될 때 람다를 전달할 수 있게 합니다. 이전에는 Java 메서드와 Kotlin에서 Java 인터페이스를 다룰 때만 SAM 변환을 적용할 수 있었지만 이제는 Kotlin 함수와 인터페이스에서도 사용할 수 있습니다.

Kotlin은 이제 Kotlin 인터페이스에 대한 SAM 변환을 지원합니다. Java와는 다르게 동작합니다. Kotlin 인터페이스를 명시적으로 표시해야 합니다. fun 키워드로 인터페이스를 표시한 후 해당 인터페이스가 매개변수로 예상되는 경우 람다를 인수로 전달할 수 있습니다.

 

fun interface Action {
    fun run()
}

fun runAction(a: Action) = a.run()

fun main() {
    runAction {
        println("Hello, Kotlin 1.4!")
    }
}

 

Kotlin은 처음부터 Java 인터페이스에 대한 SAM 변환을 지원했지만 하나의 문제가 있었습니다. Java 메서드를 호출하고 두 개의 SAM 인터페이스를 매개변수로 전달해야 하는 경우 두 인자를 모두 람다 또는 일반 객체로 전달해야 했습니다. 람다를 하나는 람다로, 다른 하나는 객체로 전달하는 것은 불가능했습니다. 새로운 알고리즘은 이 문제를 해결하며 어떤 경우에도 SAM 인터페이스 대신 람다를 전달할 수 있게 합니다. 이것은 자연스러운 예상 방법입니다.

 

더 많은 사용 사례에서 자동으로 타입 추론


새로운 추론 알고리즘은 이전 추론에서 명시적으로 타입을 지정해야 했던 많은 경우에 대한 타입을 자동으로 추론합니다. 예를 들어 다음 예제에서 람다 매개변수 it의 타입은 String?로 올바르게 추론됩니다.

 

val rulesMap: Map<String, (String?) -> Boolean> = mapOf(
    "weak" to { it != null },
    "medium" to { !it.isNullOrBlank() },
    "strong" to { it != null && "^[a-zA-Z0-9]+$".toRegex().matches(it) }
)

 

Kotlin 1.3에서는 명시적으로 람다 매개변수를 도입하거나 명시적인 제네릭 인자가 있는 Pair 생성자로 바꾸어야 했습니다.

 

람다의 마지막 표현식에 대한 스마트 캐스트


Kotlin 1.3에서는 람다 내부의 마지막 표현식이 예상 타입을 명시하지 않으면 스마트 캐스트되지 않습니다. 따라서 다음 예제에서 Kotlin 1.3은 결과 변수의 타입으로 String?을 추론합니다.

 

val result = run {
    var str = currentValue()
    if (str == null) {
        str = "test"
    }
    str // Kotlin 컴파일러는 str이 여기에서 null이 아님을 알고 있습니다.
}

 

Kotlin 1.4에서는 새로운 추론 알고리즘 덕분에 람다 내부의 마지막 표현식이 스마트 캐스트되며 이 새로운, 더 정확한 타입이 결과 람다 타입을 추론하는 데 사용됩니다. 따라서 결과 변수의 타입은 String이 됩니다.

Kotlin 1.3에서 이러한 경우를 작동하게 하려면 명시적인 캐스트(!! 또는 as String과 같은 타입 캐스트)를 추가해야 했지만 이제 이러한 캐스트가 불필요하게 되었습니다.


Callable 참조에 대한 스마트 캐스트


Kotlin 1.3에서는 스마트 캐스트 타입의 멤버 참조에 액세스할 수 없었습니다. 이제 가능합니다.

 

fun perform(animal: Animal) {
    val kFunction: KFunction<*> = when (animal) {
        is Cat -> animal::meow
        is Dog -> animal::woof
    }
    kFunction.call()
}

 

animal 변수가 특정 타입 Cat 및 Dog로 스마트 캐스트 된 후에는 서브타입에 해당하는 멤버 참조에 액세스할 수 있습니다.


기본 인수 값을 가진 함수에 대한 Callable 참조의 더 나은 추론


기본 인수 값을 가진 함수에 대한 callable 참조를 사용하는 것이 이제 더 편리합니다. 예를 들어 다음 foo 함수에 대한 callable 참조는 하나의 Int 인수를 받는 함수 또는 인수를 받지 않는 함수로 해석될 수 있습니다.

 

fun foo(i: Int = 0): String = "$i!"

fun apply1(func: () -> String): String = func()
fun apply2(func: (Int) -> String): String = func(42)

fun main() {
    println(apply1(::foo))
    println(apply2(::foo))
}

 

위 예제에서 callable 참조는 Int 인수를 받는 함수 또는 인수를 받지 않는 함수 중 어떤 것으로 해석될 수 있습니다.

 

위임된 프로퍼티에 대한 더 나은 추론


위임된 프로퍼티의 타입은 by 키워드 다음에 오는 대리자 식을 분석할 때 고려되지 않았습니다. 예를 들어 다음 코드는 이전에 컴파일되지 않았지만 이제는 컴파일러가 이전 및 새 매개변수의 타입을 String?로 올바르게 추론합니다.

 

import kotlin.properties.Delegates

fun main() {
    var prop: String? by Delegates.observable(null) { p, old, new ->
        println("$old → $new")
    }
    prop = "abc"
    prop = "xyz"
}

 

언어 변경 사항

 

대부분의 언어 변경 내용은 이전 블로그 게시물에서 이미 설명되었습니다:

  • Kotlin 클래스에 대한 SAM 변환
  • 이름 지정 및 위치 지정 인수 혼합 사용
  • 최적화된 위임된 프로퍼티
  • 후행 쉼표
  • when 구문 내에서 break 및 continue 지원
  • 꼬리 재귀 함수에 대한 변경 사항

 

이 게시물에서는 계약(contract)에 관한 몇 가지 작은 개선 사항을 강조하겠습니다.


계약 지원


사용자 정의 계약을 정의하는 구문은 여전히 실험적입니다. 그러나 계약이 유용할 수 있는 몇 가지 새로운 경우를 지원하고 있습니다.

이제 reified 제네릭 유형 매개변수를 사용하여 계약을 정의할 수 있습니다. 예를 들어, 다음과 같은 계약을 assertIsInstance 함수에 구현할 수 있습니다.

 

@OptIn(ExperimentalContracts::class)
inline fun <reified T> assertIsInstance(value: Any?) {
    contract {
        returns() implies (value is T)
    }
    
    assertTrue(value is T)
}

 

T 유형 매개변수가 reified로 선언되었으므로 함수 본문에서 그 유형을 확인할 수 있습니다. 이와 유사한 함수가 나중에 kotlin.test 라이브러리에 단언 메시지와 함께 추가될 예정입니다.

또한 이제 최종 멤버에 대한 사용자 정의 계약을 정의할 수 있습니다. 이전에는 멤버 함수에 대한 계약을 완전히 금지했습니다. 왜냐하면 계약을 계층 구조의 해당 계약으로 표현하는 계약의 계층을 의미하기 때문에 몇 가지 계약을 정의할 때는 설계 및 논의의 문제였습니다. 그러나 멤버 함수가 최종이며 다른 함수를 오버라이드하지 않는 경우에는 해당 함수에 대한 계약을 정의하는 것이 안전합니다.

 

표준 라이브러리 변경 사항


표준 라이브러리에서 사용 중지된 실험적인 코루틴 제외


kotlin.coroutines.experimental API는 1.3.0에서 kotlin.coroutines을 선호하여 사용 중지되었습니다. 1.4-M1에서는 kotlin.coroutines.experimental을 표준 라이브러리에서 제거하여 사용 중지 주기를 완료합니다. JVM에서 여전히 사용하는 사람들을 위해 실험적인 코루틴 API를 모두 포함한 kotlin-coroutines-experimental-compat.jar 호환성 아티팩트를 제공합니다. 이것은 maven에 게시하고 표준 라이브러리와 함께 Kotlin 배포에 포함할 예정입니다. 현재 우리는 1.4-M1 아티팩트와 함께 bintray 저장소에 게시했습니다.


사용 중지된 mod 연산자 제거


다른 사용 중지된 함수는 숫자 형식에서 나머지 연산 후 나머지를 계산하는 mod 연산자입니다. Kotlin 1.1에서 이것은 rem() 함수로 대체되었습니다. 이제 우리는 표준 라이브러리에서 완전히 제거합니다.


부동 소수점 형식에서 Byte 및 Short로의 변환 중단


표준 라이브러리에는 부동 소수점 숫자를 정수 형식으로 변환하는 함수가 포함되어 있습니다: toInt(), toShort(), toByte(). 부동 소수점 숫자를 Short 및 Byte로 변환하는 것은 좁은 값 범위와 작은 변수 크기 때문에 예기치 않은 결과를 초래할 수 있습니다. 이러한 문제를 피하기 위해 1.4-M1에서 Double 및 Float에서 toShort() 및 toByte() 함수를 사용 중지합니다. 여전히 부동 소수점 숫자를 Byte 또는 Short로 변환해야 하는 경우 두 단계 변환을 사용하세요: 먼저 Int로 변환한 다음 대상 형식으로 변환합니다.

 

공통 리플렉션 API


우리는 공통 리플렉션 API를 재검토했습니다. 이제 이 API에는 모든 세 개의 대상 플랫폼 (JVM, JS, Native)에서 사용 가능한 멤버만 포함되어 있으므로 모든 플랫폼에서 동작하는 동일한 코드임을 확신할 수 있습니다.


use() 및 시간 측정 함수를 위한 새로운 계약


표준 라이브러리에서 계약 사용을 확대하고 있습니다. 1.4-M1에서는 use() 함수 및 시간 측정 함수 measureTimeMillis() 및 measureNanoTime()에 대한 코드 블록의 단일 실행을 선언하는 계약을 추가했습니다.


Kotlin 리플렉션을위한 Proguard 구성


1.4-M1부터 kotlin-reflect.jar에 Kotlin Reflection을위한 Proguard/R8 구성이 포함되었습니다. 이를 통해 R8 또는 Proguard를 사용하는 대부분의 Android 프로젝트는 추가 구성 없이 kotlin-reflect와 함께 작동해야합니다. 더 이상 kotlin-reflect 내부의 Proguard 규칙을 복사하여 붙여 넣을 필요가 없습니다. 그러나 사용할 모든 API를 명시적으로 나열해야한다는 점에 유의하십시오.

 

Kotlin/JVM


Kotlin은 1.3.70 버전부터 JVM bytecode (대상 버전 1.8+)에서 형식 주석을 생성하여 실행 중에 사용할 수 있게 되었습니다. 이 기능은 기존의 몇몇 Java 라이브러리를 사용하기를 훨씬 쉽게 만들며 새로운 라이브러리 작성자에게 더 많은 기능을 제공하는 것이 커뮤니티로부터 오랜 기간 요청되었습니다.

다음 예제에서는 String 형식에 있는 @Foo 주석이 bytecode에 포함되고 라이브러리 코드에서 사용될 수 있습니다:

@Target(AnnotationTarget.TYPE)
annotation class Foo
​
class A {
    fun foo(): @Foo String = "OK"
}


bytecode에 형식 주석을 생성하는 방법에 대한 자세한 내용은 Kotlin 1.3.70 릴리스 블로그 게시물의 해당 섹션을 참조하십시오.

 

Kotlin/JS


Kotlin 1.4-M1에서는 Gradle DSL의 일부 변경과 새로운 IR 컴파일러 백엔드를 포함한 몇 가지 변경 사항이 포함되어 있습니다. 이것은 최적화 및 새로운 기능을 가능하게 하는 것입니다.


Gradle DSL 변경 사항


kotlin.js 및 멀티플랫폼 Gradle 플러그인에서 중요한 새로운 설정이 도입되었습니다. build.gradle.kts 파일의 target 블록 내에서 produceExecutable() 설정이 이제 사용 가능하며, Kotlin/JS 빌드 중에 .js 아티팩트를 생성하려면 이 설정이 필요합니다.

kotlin {
    target {
        useCommonJs()
        produceExecutable()
        browser {}
    }
}


Kotlin/JS 라이브러리를 작성하는 경우 produceExecutable()을 생략할 수 있습니다. 새로운 IR 컴파일러 백엔드를 사용하는 경우(자세한 내용은 아래 참조), 이 설정을 생략하면 실행 가능한 JS 파일이 생성되지 않습니다(따라서 빌드 프로세스가 더 빨리 실행됩니다). 빌드/libs 폴더에 klib 파일이 생성되며, 이 파일은 다른 Kotlin/JS 프로젝트에서 사용하거나 동일한 프로젝트에서 종속성으로 사용할 수 있습니다. produceExecutable()을 명시적으로 지정하지 않으면 이 동작이 기본적으로 발생합니다.

produceExecutable()을 사용하면 JavaScript 생태계에서 실행 가능한 코드가 생성됩니다. 이는 자체 진입점 또는 JavaScript 라이브러리로 사용됩니다. 이로 인해 실제 JavaScript 파일이 생성되며, 노드 인터프리터에서 실행하거나 HTML 페이지에 포함시켜 브라우저에서 실행하거나 JavaScript 프로젝트의 종속성으로 사용할 수 있습니다.


새로운 IR 컴파일러 백엔드


Kotlin 1.4-M1은 Kotlin/JS 대상용으로 새로운 IR 컴파일러 백엔드를 포함한 첫 번째 버전입니다. 이 백엔드는 크게 개선된 최적화의 기반이 되며 Kotlin/JS가 JavaScript 및 TypeScript와 상호 작용하는 방식에 일부 변경 사항을 가져옵니다. 아래에서 소개하는 기능은 모두 새로운 IR 컴파일러 백엔드를 대상으로 합니다. 아직 기본 설정으로 활성화되지 않았지만 프로젝트에서 이를 시도하고 라이브러리를 새로운 백엔드에 대비하여 준비하고 물론 문제를 발견하면 피드백을 제공하고 문제를 보고하도록 권장합니다.


새로운 백엔드 사용하기


새로운 백엔드를 사용하려면 gradle.properties 파일에서 다음 플래그를 설정하십시오.

 

kotlin.js.compiler=ir


IR 컴파일러 백엔드와 기본 백엔드 모두에서 라이브러리를 생성해야 하는 경우 이 플래그를 both로 대체로 설정할 수도 있습니다. 이 플래그가 정확히 무엇을 하는지는 이 블로그 게시물의 "Both-mode" 섹션에서 제공됩니다. 이 플래그는 새로운 및 기본 컴파일러 백엔드가 이진 호환되지 않기 때문에 필요합니다.


이진 호환성 없음


새로운 IR 컴파일러 백엔드의 주요 변경 사항 중 하나는 기본 백엔드와의 이진 호환성이 없다는 점입니다. Kotlin/JS의 두 백엔드 간에는 이러한 호환성이 없으므로 새로운 IR 컴파일러 백엔드로 생성된 라이브러리를 기본 백엔드에서 사용하거나 그 반대로 사용할 수 없습니다.

프로젝트에서 IR 컴파일러 백엔드를 사용하려면 모든 Kotlin 종속성을 이 새로운 백엔드를 지원하는 버전으로 업데이트해야 합니다. JetBrains이 Kotlin 1.4-M1을 대상으로 Kotlin/JS용으로 게시한 라이브러리에는 이미 새로운 IR 컴파일러 백엔드와 함께 사용하기 위한 모든 아티팩트가 포함되어 있습니다. 이러한 라이브러리에 종속성을 지정할 때 Gradle이 올바른 아티팩트를 자동으로 선택합니다(즉, IR별 좌표를 지정할 필요가 없음). 일부 라이브러리(예: kotlin-wrappers)는 새로운 IR 컴파일러 백엔드의 특정 특성을 의존하기 때문에 문제가 있을 수 있습니다. 이 문제를 인식하고 향후 이 기능을 개선하기 위해 노력 중입니다.

현재 컴파일러 백엔드 및 새로운 IR 컴파일러 백엔드를 모두 지원하도록 라이브러리를 제공하려는 라이브러리 작성자이고 이와 관련된 지침을 찾고 있다면 이 블로그 게시물의 "Both-mode" 섹션도 확인하십시오.

다음 섹션에서는 새로운 컴파일러에서 기대할 수 있는 일부 이점과 차이점을 자세히 살펴보겠습니다.


최적화된 DCE


새로운 IR 컴파일러 백엔드는 기본 백엔드와 비교하여 훨씬 공격적인 최적화를 수행할 수 있습니다. 생성된 코드는 정적 분석기와 더 잘 작동하며, 생성된 코드를 Google의 Closure Compiler를 통해 실행하고 고급 모드 최적화를 사용하는 것도 가능합니다(단, Kotlin/JS Gradle 플러그인은 이에 대한 특별한 지원을 제공하지 않음에 유의하십시오).

가장 눈에 띄는 변경 사항은 생성된 아티팩트의 코드 크기에서 나타납니다. 개선된 죽은 코드 제거 방법을 통해 아티팩트 크기가 크게 축소됩니다. 예를 들어 "Hello, World!" Kotlin/JS 프로그램은 약 1.7 KiB로 축소됩니다. 더 복잡한(데모) 프로젝트인 kotlinx.coroutines를 사용하는 예제 프로젝트와 같이 경우에 따라 숫자가 크게 바뀌었으며, 아마도 스스로 말해줄 것입니다.

 



아직 설득되지 않았다면 직접 시도해 보십시오. Kotlin 1.4-M1에서 DCE와 번들링은 두 백엔드 모두에서 기본으로 활성화되어 있습니다!

 

JavaScript로 선언 내보내기


IR 컴파일러 백엔드를 사용할 때 public으로 표시된 선언은 자동으로 내보내지 않습니다(이름이 매핑된 버전조차도). 이것은 IR 컴파일러의 닫힌 세계 모델이 내보낼 선언을 명시적으로 주석 처리한다고 가정하기 때문입니다. JavaScript 또는 TypeScript에서 최상위 선언을 외부로 사용할 수 있게하려면 @JsExport 주석을 사용하십시오. 다음 예제에서는 KotlinGreeter (및 해당 메서드)와 farewell()을 JavaScript에서 사용할 수 있도록하지만 secretGreeting()은 Kotlin에서만 사용합니다.

 

package blogpost
​
@JsExport
class KotlinGreeter(private val who: String) {
    fun greet() = "Hello, $who!"
}
​
@JsExport
fun farewell(who: String) = "Bye, $who!"
​
fun secretGreeting(who: String) = "Sup, $who!" // only from Kotlin!


프리뷰: TypeScript 정의


새로운 Kotlin/JS IR 컴파일러의 또 다른 기능은 Kotlin 코드에서 TypeScript 정의를 생성하는 것입니다. 이러한 정의는 혼합 앱에서 작업할 때 JavaScript 도구 및 IDE에서 사용될 수 있으며 자동 완성을 제공하고 정적 분석기를 지원하며 JavaScript 및 TypeScript 프로젝트에 Kotlin 코드를 포함시키기가 더 쉬워집니다.

@JsExport로 표시된 최상위 선언(위의 예 참조)을 사용하는 프로젝트가 produceExecutable()을 사용하도록 구성된 경우 TypeScript 정의를 포함하는 .d.ts 파일이 생성됩니다. 위의 코드 조각의 경우 다음과 같이 보입니다.

 

// [...]
namespace blogpost {
    class KotlinGreeter {
        constructor(who: string)
        greet(): string
    }
    function farewell(who: string): string
}
// [...]


Kotlin 1.4-M1에서 이러한 선언은 미리 보기로만 제공되며 현재는 기본 설정으로 배포 폴더에 추가되지 않습니다. 이 동작이 향후 변경될 것으로 예상됩니다.

Both-mode


라이브러리 유지 관리자가 새로운 IR 컴파일러 백엔드로 이동하기 쉽도록 하기 위해 gradle.properties에서 kotlin.js.compiler 플래그의 추가 설정이 도입되었습니다.

 

kotlin.js.compiler=both


Both 모드에서는 소스에서 라이브러리를 빌드할 때 두 컴파일러 백엔드 모두를 사용합니다(따라서 이름이 그래서 지어졌습니다). 이것은 Kotlin IR로 klib 파일뿐만 아니라 기본 컴파일러를 위한 jar 파일도 생성합니다. 동일한 Maven 좌표로 게시할 때 Gradle은 사용 사례에 따라 올바른 아티팩트를 자동으로 선택합니다. 이것은 기본 백엔드를 사용하는 프로젝트와 새로운 IR 컴파일러 백엔드를 이미 업그레이드한 프로젝트 모두에 대해 라이브러리를 컴파일하고 게시할 수 있음을 의미합니다. 이것은 사용자 중 일부가 아직 기본 백엔드를 사용 중인 경우에도 경험을 망가뜨리지 않도록 도와줍니다(단, 프로젝트를 1.4-M1로 업그레이드했음이 가정됩니다).

그러나 현재 IDE는 both 모드로 의존성 및 현재 프로젝트를 빌드할 때 라이브러리 참조를 올바르게 해결하지 못하는 문제가 있습니다. 이 문제를 인식하고 곧 수정할 것입니다.

 

Kotlin/Native

 

Objective-C에서의 제네릭 지원 (기본 설정)


이전 버전의 Kotlin은 Objective-C 상호 운용에서 제네릭을 실험적으로 지원했습니다. Kotlin 코드에서 제네릭을 포함한 프레임워크 헤더를 생성하려면 -Xobjc-generics 컴파일러 옵션을 사용해야했습니다. 1.4-M1에서는 이 동작이 기본 설정으로 변경됩니다. 이로 인해 기존의 Objective-C 또는 Swift 코드가 Kotlin 프레임워크를 호출하는 경우 일부 상황에서 문제가 발생할 수 있습니다. 제네릭 없이 프레임워크 헤더를 작성하려면 -Xno-objc-generics 컴파일러 옵션을 추가하십시오.

 

binaries.framework {
    freeCompilerArgs += "-Xno-objc-generics"
}


Objective-C/Swift 상호 운용에서 예외 처리 변경


1.4에서는 Kotlin에서 생성된 Swift API의 예외 번역 방식에 약간의 변경 사항이 있습니다. Kotlin과 Swift 사이에는 오류 처리에 대한 기본적인 차이가 있습니다. 모든 Kotlin 예외는 확인되지 않은 예외이며 Swift는 확인된 오류만 가지고 있습니다. 따라서 Swift 코드가 예상된 예외를 인식하도록하려면 Kotlin 함수에 @Throws 주석을 지정하고 가능한 예외 클래스 목록을 지정해야합니다.
Swift 또는 Objective-C 프레임워크로 컴파일 할 때 @Throws 주석이 있는 함수는 Objective-C에서 NSError*을 생성하는 메서드로 나타내며 Swift에서는 throws 메서드로 나타납니다.
이전에는 RuntimeException 및 Error 이외의 모든 예외가 NSError로 전파되었습니다. 1.4-M1에서는 이 동작이 변경되었습니다. 이제 NSError는 @Throws 주석의 매개 변수로 지정된 클래스 (또는 해당 하위 클래스)의 인스턴스에만 throw됩니다. Swift/Objective-C에 도달하는 다른 Kotlin 예외는 처리되지 않았으며 프로그램 종료를 유발합니다.


성능 향상


Kotlin/Native 컴파일 및 실행의 전반적인 성능을 지속적으로 향상시키고 있습니다. 1.4-M1에서는 일부 벤치마크에서 최대 2배 빠르게 작동하는 새로운 객체 할당기를 제공합니다. 현재 이 새로운 할당기는 실험적인 상태이며 기본으로 사용되지 않습니다. -Xallocator=mimalloc 컴파일러 옵션을 사용하여 이를로 전환할 수 있습니다.


호환성


Kotlin 1.4는 일부 코너 케이스에서 1.3과 역호환되지 않습니다. 이러한 모든 사례는 언어 위원회에서 신중하게 검토했으며 "호환성 가이드"에 나열될 것입니다. 현재는 이 목록을 YouTrack에서 찾을 수 있습니다.

오버로드 결정 규칙이 약간 변경될 수 있습니다. 이름이 같고 서명이 다른 여러 함수가 있는 경우 Kotlin 1.4에서 호출되는 함수는 Kotlin 1.3에서 선택된 함수와 다를 수 있습니다. 그러나 이러한 변경 사항은 일부 코너 케이스에서만 발생하며 실제로는 매우 드물게 발생할 것으로 예상됩니다. 또한 오버로드된 함수가 유사하게 작동하여 결국 서로 호출하는 것으로 가정하고 있으며 이러한 변경 사항이 프로그램 동작에 영향을 미치지 않아야한다고 가정합니다. 그러나 일반적으로 제네릭 및 다양한 오버로드를 사용하여 복잡한 코드를 작성하는 경우에 주의하십시오. 이러한 종류의 모든 사례는 위에서 언급한 호환성 가이드에 나열됩니다.

 

사전 릴리스 노트


역호환성 보증이 사전 릴리스 버전에 적용되지 않음을 주의하세요. 기능 및 API는 이후 릴리스에서 변경될 수 있습니다. 최종 RC에 도달하면 사전 릴리스 버전에서 생성된 모든 이진 파일이 컴파일러에 의해 금지될 것이며, 1.4‑Mx에서 컴파일된 모든 것을 다시 컴파일해야할 것입니다.


어떻게 시도할 수 있는지


항상처럼 Kotlin을 온라인에서 play.kotl.in에서 시도해 볼 수 있습니다.

IntelliJ IDEA 및 Android Studio에서 Kotlin 플러그인을 버전 1.4-M1로 업데이트할 수 있습니다. 이를 어떻게 하는지에 대한 자세한 내용은 해당 IDE의 도움말을 참조하십시오.

미리보기 버전을 설치하기 전에 생성된 프로젝트에서 작업하려면 Gradle 또는 Maven에서 미리보기 버전을 사용하도록 빌드를 구성해야합니다.

GitHub 릴리스 페이지에서 명령 줄 컴파일러를 다운로드할 수 있습니다.

이 릴리스와 함께 게시된 라이브러리 버전은 다음과 같습니다.

  • kotlinx.atomicfu 버전: 0.14.2-1.4-M1
  • kotlinx.coroutines 버전: 1.3.5-1.4-M1
  • kotlinx.serialization 버전: 0.20.0-1.4-M1
  • ktor 버전: 1.3.2-1.4-M1


릴리스 세부 정보 및 호환되는 라이브러리 목록은 여기에서도 확인할 수 있습니다.


피드백을 공유해 주세요


버그를 발견하고 이를 issue tracker인 YouTrack에 보고해 주시면 우리는 감사할 것입니다. 중요한 문제를 최종 릴리스 이전에 해결하기 위해 노력할 것이며, 이는 여러분이 문제가 해결되기를 기다리지 않아도 된다는 것을 의미합니다.

질문이 있거나 토론에 참여하려면 Kotlin Slack의 #eap 채널에 참여해 주세요 (여기에서 초대를 받을 수 있습니다). 이 채널에서는 새로운 미리보기 빌드에 대한 알림도 받을 수 있습니다.

함께 Kotlin을 즐겨보세요!

 

외부 기여자


우리는 Proguard 구성을 kotlin-reflect에 내장하는 데 기여한 Zac Sweers에게 특히 감사드립니다.

이 릴리스에 포함된 우리의 모든 외부 기여자들에게 감사드립니다:

  • Steven Schäfer
  • Toshiaki Kameyama
  • pyos
  • Mads Ager
  • Mark Punzalan
  • Juan Chen
  • Kristoffer Andersen
  • Alfredo Delli Bovi
  • Jinseong Jeon
  • Jonathan Leitschuh
  • Sebastian Schuberth
  • Ivan Gavrilovic
  • David Schreiber-Ranner
  • Miguel Serra
  • Alex Chmyr
  • Fleshgrinder
  • Aleksey Kladov
  • Will Boyd
  • Dominic Fischer
  • Kenji Tomita
  • Stéphane Nicolas
  • Tillmann Berg
  • Kevin Bierhoff
  • Tsvetan

 

원문

 

https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-4-m1-released/

반응형

댓글