본문 바로가기
Kotlin/Release Notes

[Kotlin Release Notes] Kotlin 1.4-M3 is Out: Standard Library Changes

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

2020년 7월 6일

 

오늘은 Kotlin 1.4의 마지막 마일스톤 미리보기인 1.4-M3을 소개해 드립니다. 이 게시물에서는 이 미리보기가 Kotlin 표준 라이브러리에 가져온 변경 사항을 안내하겠습니다. M3에서 다른 구성 요소도 업데이트되고 있으며, 이를 다루는 것은 나중에 릴리스 후보 버전(1.4-RC)을 포함하여 다른 블로그 게시물에서 다룰 것입니다. 이 버전에서 Kotlin 1.4의 범위를 최종으로 확정짓게 됩니다.

1.4-M3에서의 표준 라이브러리 변경 사항은 다음과 같습니다:

  • JVM 라이브러리에 모듈 정보 기술자(module-info)가 추가되었습니다.
  • 표준 라이브러리에 함수형 인터페이스가 추가되었습니다.
  • 현실적인 상황을 다루는 새로운 컬렉션 작업들이 추가되었습니다.
  • 공통 라이브러리에 @Throws 어노테이션이 추가되었습니다.
  • 부동 소수점 배열에서 일부 함수들이 폐지되었습니다.

 

변경 사항의 완전한 목록은 변경 로그에서 확인할 수 있습니다. 항상 외부 기여자들에게 감사드립니다.

이 미리보기를 시도하고 피드백을 공유해 주시면 매우 감사하겠습니다.

 

표준 라이브러리 아티팩트에 모듈 정보 기술자 포함


Java 9부터 Jigsaw 프로젝트를 통해 응용 프로그램을 모듈화할 수 있게 되었습니다. jlink 도구를 사용하여 앱에 필요한 플랫폼 모듈만 포함된 사용자 정의 Java 런타임 이미지를 생성할 수 있습니다. 이전에도 Kotlin 표준 라이브러리 아티팩트를 jlink와 함께 사용할 수 있었지만 "modular" 분류를 가진 별도의 아티팩트를 사용해야 했으며 전체 설정이 복잡했습니다. 모듈 설명자를 주요 아티팩트에 포함시킬 수 없던 이유는 Android 도구에서 발생한 문제로 인해 발생했으며 이 문제는 이제 해결되었습니다.

Kotlin 1.4에서는 기본 표준 라이브러리 아티팩트에 module-info.java 모듈 정보를 추가하여 jlink와 쉽게 사용할 수 있습니다. Android에서는 Android Gradle 플러그인 버전 3.2 이상을 사용하십시오. 이 버전은 모듈 정보를 가진 jar 파일을 올바르게 처리할 수 있습니다.


표준 라이브러리에서의 함수형 인터페이스(fun interface)


Kotlin 1.4는 Kotlin 클래스에 대한 SAM(단일 추상 메서드) 변환을 지원합니다. 단일 추상 메서드만 포함하는 인터페이스를 fun interface로 표시한 다음 해당 인터페이스가 매개변수로 예상될 때 람다를 인수로 전달할 수 있습니다. 표준 라이브러리에서 다음 인터페이스들이 fun interface로 선언되었습니다:

  • Comparator
  • ReadOnlyProperty
  • PropertyDelegateProvider (1.4-M2에서 도입되었습니다)

 

람다를 매개변수로 받는 SAM 생성자를 사용하여 인스턴스를 만들 수 있습니다. 결과 코드는 훨씬 간단해집니다.

 

 

컬렉션 작업


- 새로운 sumOf 함수는 선택기 함수를 취하고 해당 값의 합계를 컬렉션의 모든 요소에 반환합니다. 기존의 sumBy 및 sumByDouble 함수와 매우 유사합니다. 주요 차이점은 새로운 sumOf 함수가 다양한 반환 유형을 가진 선택기를 취한다는 것입니다. 따라서 sumOf는 Int, Long, Double, UInt, ULong 유형의 합계를 생성할 수 있으므로 서로 다른 유형의 합계를 동일한 방식으로 처리할 수 있습니다. 또한 JVM에서는 BigInteger 및 BigDecimal도 사용할 수 있습니다.

 

val order = listOf<OrderItem>(
    OrderItem("Cake", price = 10.0, count = 1),
    OrderItem("Coffee", price = 2.5, count = 3),
    OrderItem("Tea", price = 1.5, count = 2))
​
val total = order.sumOf { it.price * it.count} // Double
val count = order.sumOf { it.count } // Int


- min 및 max 함수는 minOrNull 및 maxOrNull로 이름이 변경되었습니다. 1.0에서 도입된 이후, min 및 max는 빈 컬렉션에 대해 null을 반환했습니다. 이는 Kotlin 컬렉션 API에서 사용되는 네이밍 컨벤션과 충돌합니다. *OrNull 접미사가 없는 함수는 수신 컬렉션이 비어 있으면 예외를 throw합니다. null 대신에 null을 얻으려면 *OrNull 버전의 함수를 사용해야 합니다. 예를 들어, firstOrNull을 사용하세요.
따라서 우리는 min 및 max의 동작을 점진적으로 변경하기로 결정했습니다. 1.4-M3에서는 min 및 max에 대한 동의어인 minOrNull 및 maxOrNull을 추가하고 min 및 max에 대한 비null 반환 유형으로 다시 도입하기 위해 폐기 주기를 시작합니다.

 

val order = listOf<OrderItem>(
    OrderItem("Cake", price = 10.0, count = 1),
    OrderItem("Coffee", price = 2.5, count = 3),
    OrderItem("Tea", price = 1.5, count = 2))
​
val highestPrice = order.maxOf { it.price }


- 기존 API와 일관성을 유지하기 위해 return 유형과 일치하지 않는 변환을 사용할 수 있도록 flatMap 및 flatMapTo에 대한 새로운 오버로드가 추가되었습니다. 구체적으로 다음과 같습니다.

  • Iterable, Array 및 Map에 대한 Sequence 변환
  • Sequence에 대한 Iterable 변환

 

val list = listOf("kot", "lin")
val lettersList = list.flatMap { it.asSequence() }
val lettersSeq = list.asSequence().flatMap { it.toList() }


- 새로운 flatMapIndexed 함수가 flatMap의 대응본으로 추가되었습니다. 이미 알고 계실 것처럼 컬렉션 처리 함수의 이름에 "Indexed"가 포함되면 적용된 작업에 요소 인덱스가 매개 변수로 포함됩니다.

 

val list = listOf("hello", "kot", "lin", "world")
val kotlin = list.flatMapIndexed { index, item ->
    if (index in 1..2) item.toList() else emptyList() 
}


일반적인 @Throws 주석


Kotlin은 확인된 예외를 가지고 있지 않지만 Java 및 Swift와 같은 언어와의 상호 운용성을 위해 @Throws 주석을 사용합니다. 이전에는 JVM (kotlin.jvm.Throws) 및 Native (kotlin.native.Throws)용으로 별도의 이름을 가진 이 주석들이 있었습니다.
1.4-M3부터 @Throws 주석은 공통 라이브러리의 일부로 직접 kotlin 패키지 (kotlin.Throws)에 사용할 수 있게 되어 공통 코드에서 사용할 수 있게 되었습니다.


Swift 및 Objective-C에서의 @Throws가 포함된 suspend 함수


1.4-M1에서는 Objective-C/Swift 상호 운용성에서 예외 처리에 대한 변경 사항을 발표했습니다. 이제 NSError는 @Throws 주석의 매개 변수로 지정된 클래스 (또는 그 하위 클래스)의 인스턴스에 대해서만 throw됩니다. 1.4-M2에서는 Kotlin의 suspending 함수를 Swift 및 Objective-C에서 기본적으로 지원하도록 변경 사항을 발표했습니다. 1.4-M3에서는 @Throws 주석이 지정된 suspend fun의 동작에 작은 변경 사항이 있습니다.

  • @Throws로 주석이 달린 suspend fun이 있는 경우 @Throws 주석의 매개 변수로 CancellationException::class를 지정해야 합니다. 그렇지 않으면 컴파일 오류가 발생합니다.
  • suspend fun에 @Throws 주석이 없는 경우 Swift에서 호출할 때 암시적으로 @Throws(CancellationException::class)을 사용합니다.


부동 소수점 배열에서의 동등성


컨테이너 유형에 대한 이러한 편리한 확장 함수인 contains, indexOf 및 lastIndexOf를 알고 계신 분들이 많을 것입니다. 얼마 전에 부동 소수점 배열 (FloatArray 및 DoubleArray)에서의 이러한 함수의 동작이 논란이 될 수 있고 잘못된 것처럼 보일 수 있다는 것을 알게 되었습니다.
구체적으로 IEEE 754 표준을 사용하여 부동 소수점 산술을 정의합니다. 이 표준은 다음과 같은 경계 조건에 대한 동등성 규칙을 정의합니다.

  • NaN은 NaN과 동일하지 않습니다.
  • -0.0은 0.0과 동일합니다.


이러한 규칙은 예상치 못한 결과를 초래할 수 있습니다. 예를 들어 다음과 같습니다.

 

val darray = doubleArrayOf(Double.NaN, 0.0)
println (darray.contains(darray[0])) // false!


또한 이러한 동작은 같은 함수가 목록에서 작동하는 방식과 일관성이 없습니다. 왜냐하면 목록은 총 주문 동등성을 사용하기 때문입니다.

 

val listOfDouble: List<Double> = listOf(0.0, Double.NaN)
val listFromArray: List<Double> = doubleArrayOf(0.0, Double.NaN).asList()
​
println(listOfDouble.contains(Double.NaN))  // true
println(listFromArray.contains(Double.NaN))  // false (이전 버전에서)


1.4-M3에서는 FloatArray 및 DoubleArray의 contains, indexOf 및 lastIndexOf 확장 함수에 대한 폐기 주기를 시작합니다. 이러한 함수를 사용하려고 시도할 때 경고와 대체 지침이 표시됩니다. 향후 릴리스에서 폐기 수준을 ERROR로 강화하고 이러한 함수를 공개 API에서 제거할 예정입니다.

 

KType에서 자바 타입으로 변환

 

Kotlin 1.3.40에서는 표준 라이브러리에 유용한 typeOf 함수를 추가했습니다. 이 함수는 주어진 reified 타입 T의 런타임 표현을 KType의 인스턴스로 반환합니다. 그러나 많은 실제 사용 사례에서 KType 대신 Java 리플렉션 java.lang.reflect.Type 객체와 작업해야 할 때가 있습니다. 필요한 변환을 수행하는 것은 이미 가능했지만 전체 kotlin-reflect 종속성을 사용해야 했습니다. 이제 표준 라이브러리에 KType를 Java Type으로 변환하는 방법이 포함되어 있습니다. KType.javaType 확장 속성을 사용하면 Java Type을 반환합니다.

예를 들어:

import kotlin.reflect.javaType
import kotlin.reflect.typeOf

@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T> accessReifiedTypeArg() {
   val kType = typeOf<T>()
   println("Kotlin type: $kType")
   println("Java type: ${kType.javaType}")
}

@OptIn(ExperimentalStdlibApi::class)
fun main() {
   accessReifiedTypeArg<String>()
   // Kotlin type: kotlin.String
   // Java type: class java.lang.String
  
   accessReifiedTypeArg<List<String>>()
   // Kotlin type: kotlin.collections.List<kotlin.String>
   // Java type: java.util.List<java.lang.String>
}


다만, 현재 KType.javaType로 얻은 Java Type은 일부 특수한 경우(주석이 달린 타입 매개 변수 또는 선언 사이트 변성과 같은)에 올바르게 동작하지 않습니다. 따라서 KType.javaType은 실험적인 상태로 남아 있습니다. 지원되지 않는 경우에 대한 자세한 내용은 이 이슈에서 확인할 수 있습니다.


호환성


Kotlin 1.4는 일부 특수한 경우에는 1.3과 하위 호환성이 없습니다. 이러한 모든 경우는 언어 위원회에서 신중하게 검토되었으며 "호환성 가이드"에 나열됩니다(이와 유사한 것). 현재는 YouTrack에서 이 목록을 찾을 수 있습니다.

 

릴리스 노트


역 호환성 보증은 프리릴리스 버전을 대상으로 하지 않습니다. 기능 및 API는 이후 릴리스에서 변경될 수 있습니다. 최종 RC에 도달하면 프리릴리스 버전에서 생성된 모든 이진 파일이 컴파일러에 의해 금지될 것이며, 1.4-Mx로 컴파일된 모든 것을 다시 컴파일해야 합니다.


최신 기능을 사용법


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

IntelliJ IDEA 및 Android Studio에서 Kotlin 플러그인을 버전 1.4-M3로 업데이트할 수 있습니다. 이렇게 하는 방법은 여기에서 확인할 수 있습니다.

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

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

이 릴리스와 함께 게시된 라이브러리의 다음 버전을 사용할 수 있습니다:

  • kotlinx.atomicfu 버전: 0.14.3-1.4-M3
  • kotlinx.coroutines 버전: 1.3.7-1.4-M3
  • kotlinx.serialization 버전: 0.20.0-1.4-M3
  • ktor 버전: 1.3.2-1.4-M3

 

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


피드백 공유하기


이슈 트래커에서 제보한 모든 버그 리포트에 감사드리며, 최종 릴리스 전에 모든 중요한 문제를 해결하기 위해 최선을 다하겠습니다.

또한 Kotlin Slack의 #eap 채널에 참여하실 것을 환영합니다 (여기에서 초대를 받으실 수 있습니다). 이 채널에서 질문을 하거나 토론에 참여하고 새로운 미리 보기 빌드에 대한 알림을 받을 수 있습니다.

Kotlin으로 더 나아갑시다!


외부 기여


외부 기여자 중에서 이 릴리스에 포함된 풀 리퀘스트를 제출한 모든 분들에게 감사드립니다:

  • Toshiaki Kameyama
  • Steven Schäfer
  • Jinseong Jeon
  • pyos
  • Mark Punzalan
  • rapturemain
  • Vitaly Tihonov
  • Mads Ager
  • Subroh Nishikori
  • Juan Chen
  • gcx11
  • Robert Bares
  • Henrik Tunedal
  • Nick
  • Dmitry Borodin
  • Efeturi Money
  • Kevin Most
  • Anastasiya Krasnoryadtseva
  • Kristoffer Andersen
  • Martin Petrov
  • Matthew Gharrity
  • Mike Samuel
  • Mikhail Likholetov
  • Segun Famisa
  • Sinan Kozak
  • Vadim Semenov
  • Valeriy Vyrva
  • Victor Turansky
  • Yuku Kotani

 

원문

 

https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-is-out-standard-library-changes/

반응형

댓글