Kotlin 1.4-M3 출시: 표준 라이브러리 변경 사항

Jessie Cho

Kotlin 1.4의 최종 테스트 버전인 1.4-M3 버전을 기쁜 마음으로 소개합니다. 이번 게시글에서는 이번 테스트 버전이 Kotlin 표준 라이브러리에 추가할 변경 사항을 설명해드릴 예정입니다. 또한 M3의 기타 구성 요소에도 업데이트가 있습니다. 곧 다른 블로그 게시글을 통해 Kotlin 1.4의 마지막 버전이 될 릴리스 후보 버전(1.4-RC)에 대한 정보도 다룰 예정입니다.

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

전체 변경 목록은 변경 로그에서 확인할 수 있습니다. 언제나 그렇듯이 외부 기여자들께 진심으로 감사의 말씀을 전합니다.

테스트 버전을 사용하고 피드백을 공유해주신다면 정말 감사하겠습니다.

이제 표준 라이브러리 아티팩트에 module-info 설명자가 포함됩니다.

Java 9부터 Jigsaw 프로젝트를 활용하여 애플리케이션을 모듈화할 수 있습니다. jlink 도구를 통해 앱에 필요한 플랫폼 모듈만이 포함된 사용자 지정 Java 런타임 이미지를 생성할 수 있습니다. 이전에도 jlink와 Kotlin 표준 라이브러리 아티팩트를 함께 사용하는 것이 가능했지만 "모듈" 분류자가 있는 별도의 아티팩트가 필요했습니다. 이러한 전체 설정은 직관적이지 않았습니다. Android 툴링 이슈로 인해 모듈 설명자를 메인 아티팩트에 추가할 수 없는 문제가 있었지만 현재는 수정되었습니다.

Kotlin 1.4에서는 module-info.java 모듈 정보를 디폴트 표준 라이브러리 아티팩트에 추가하므로 jlink와 더불어 편리하게 사용하실 수 있습니다. Android 개발 시에는 module-info가 포함된 JAR 파일을 적절히 처리할 수 있는 Android Gradle 3.2 버전 이상을 사용하세요.

표준 라이브러리의 fun interface

Kotlin 1.4는 Kotlin 클래스에 SAM 변환을 지원합니다. 단일 추상 메소드만이 포함된 인터페이스를 fun interface로 표시하고 해당 인터페이스가 매개변수로 예상될 경우 람다를 인수로 전달할 수 있습니다. 표준 라이브러리에서 fun interface로 선언된 인터페이스는 다음과 같습니다.

  • Comparator
  • ReadOnlyProperty
  • PropertyDelegateProvider (1.4-M2에 도입됨)

인스턴스 생성 시 매개변수로 람다를 사용하는 SAM 생성자 활용도 가능합니다. 이때 결과 코드가 훨씬 간결해집니다.

컬렉션 연산

  • 새로운 sumOf 함수는 선택자 함수를 사용하며 컬렉션의 모든 요소 값의 합을 반환합니다. 기존의 sumBysumByDouble 함수와 상당히 유사합니다. 주요한 차이점은 신규 sumOf 함수가 다양한 반환 유형의 선택자를 사용하므로 여러 유형의 합계를 같은 방식으로 처리할 수 있는 것입니다. 즉, sumOf 함수는 Int, Long, Double, UInt, ULong 유형의 합계를 생성합니다. 또한 JVM에서 BigIntegerBigDecimal도 지원됩니다.
  • min, max 함수의 이름이 minOrNull, maxOrNull로 변경되었습니다. 1.0 버전에서 도입된 이후 minmax 함수는 빈 컬렉션으로 null을 반환해 왔습니다. 이는 Kotlin 컬렉션 API에서 사용되는 이름 지정 규칙(*OrNull 접미어가 없는 함수는 리시버 컬렉션이 비어 있을 경우 예외를 던짐)과 모순되는 것이었습니다. 대신 null을 사용하려면 firstOrNull과 같은 *OrNull 함수 버전을 사용해야 합니다.
    그렇기에 점진적으로 minmax 함수의 동작을 변경하기로 결정했습니다. 1.4-M3에서는 minmax의 동의어로 minOrNullmaxOrNull을 추가했습니다. 또한 비 null 반환 유형으로 대신 도입하기 위해 minmax 사용이 중단되기 시작합니다.
  • 컬렉션 항목에서 제공된 선택자 함수의 최소 또는 최대 값을 반환하는 minOfmaxOf 함수를 도입했습니다. 이 함수는 map { selector }.max()!! 또는 maxBy { selector }!!.selector(또는 minminBy)를 작성하는 데 필요하지만 누락된 case 문을 지원합니다.

    또한 기존 API와 일관성을 유지하기 위해 Comparator를 인수로 사용하는 minOfWithmaxOfWith도 추가하였습니다.
    4가지 신규 함수 모두 상단에서 설명한 비 null 규칙을 따릅니다. 이 함수들은 빈 컬렉션으로 예외를 던지고 이 사례에서 null을 반환하는 *OrNull을 포함합니다.

  • flatMapflatMapTo에 대한 신규 오버로드를 활용하여 다음과 같이 리시버 유형과 일치하지 않는 반환 유형을 변환할 수 있습니다.

    • Iterable, ArrayMapSequence로 변환
    • SequenceIterable로 변환
  • 새로운 flatMapIndexed 함수가 flatMap의 대응 항목으로 추가되었습니다. 아시다시피 컬렉션 처리 함수의 이름에서 Indexed되었다는 것은 적용된 연산에 매개변수로 요소 인덱스를 포함하고 있음을 의미합니다.

일반적인 @Throws 어노테이션

비록 Kotlin은 예외를 검사하지 않지만code>@Throws 어노테이션을 사용해서 Java 및 Swift처럼 예외 검사를 하는 언어와의 상호 운용이 가능합니다. 이전에는 이름이 포함된 JVM용(kotlin.jvm.Throws) 및 Native용 (kotlin.native.Throws)으로 별도의 어노테이션이 사용되었습니다. 1.4-M3부터는 Kotlin 패키지에서 바로 일반 라이브러리의 일부인 code>@Throws 어노테이션(kotlin.Throws)이 지원되며, 이는 일반 코드에서도 사용할 수 있습니다.

Swift 및Objective-C 일시 중단 함수의 @Throws

1.4-M1에서 Objective-C/Swift 상호 운용성의 예외 처리 변경을 발표했었습니다. 이제 @Throws 어노테이션의 매개변수로서 지정된 클래스(또는 하위 클래스)의 인스턴스인 예외에만 NSError가 던져집니다. 1.4-M2에서는 기본적인 Swift/Objective-C의 Kotlin 일시 중단 함수 지원이 도입되었습니다. 1.4-M3의 경우 @Throws로 어노테이션된 일시 중단 함수의 동작에 작은 변경 사항이 있습니다.

  • @Throws를 통해 어노테이션 처리된 suspend fun이 있다면 @Throws
    어노테이션의 매개변수로 CancellationException::class를 지정해야 합니다. 그렇지 않으면 컴파일 오류가 발생합니다.
  • suspend fun @Throws 어노테이션이 없다면 Swift에서 호출 시 @Throws(CancellationException::class)가 묵시적으로 사용됩니다.

부동 소수점 배열의 상등

많은 분들께서 컨테이너 형식에 대한 contains, indexOflastIndexOf과 같은 유용한 확장 함수를 알고 계실 겁니다. 얼마 전, 저희는 부동 소수점 배열(FloatArrayDoubleArray)의 동작이 논란을 일으키고 오류로 보일 수 있다는 점을 알았습니다.
더 자세히 설명해 드리자면, 이러한 배열은 부동 소수점 계산 시 IEEE 754 표준을 사용합니다. 이 표준은 코너 케이스에 대한 다음 상등 규칙을 규정합니다.

  • NaNNaN상등하지 않다.
  • -0.00.0상등하다.

이러한 규칙은 다음과 같이 예기치 않은 결과를 초래할 수 있습니다.

또한 이러한 동작은 total order 상등을 사용하므로 같은 함수가 목록에서 작동하는 방식과 불일치합니다.

1.4-M3에서는 FloatArrayDoubleArraycontains, indexOf, lastIndexOf 확장 함수의 사용이 중단되기 시작합니다. 해당 함수를 사용하려 할 경우 함수 교체를 위한 지침과 함께 경고 메시지가 표시됩니다.
향후 릴리스에서는 중단 수준을 ERROR로 강화하고 공용 API에서 해당 함수를 제거할 예정입니다.

KType에서 Java 유형으로 변환

Kotlin 1.3.40에서 유용한 typeOf 함수가 표준 라이브러리에 추가되었습니다. 이 함수는 주어진 구체화된 유형 T의 런타임 표현을 KType의 인스턴스로 반환합니다. 하지만 여러 실제 사용 사례에서는 KType보다는 Java 리플렉션인 java.lang.reflect.Type 객체를 사용해야 합니다. 필요한 변환을 수행하는 것은 이미 가능했지만 그 과정에서 전체 kotlin-reflect 종속 요소가 사용되어야 했습니다. 이제 표준 라이브러리를 업데이트하여 KType을 Java Type으로 변환할 수 있습니다. 다음과 같이 KType.javaType 확장 속성이 Java Type을 반환합니다.

아직 일부 코너 케이스에서 보유한 Java Type이 적절히 작동하지 않을 수 있다는 점에 유의하세요(어노테이션 처리된 유형 매개변수 또는 선언 위치 변환(declaration-site variance)). KType.javaType은 실험적 단계에 있습니다. 지원되지 않는 케이스에 대한 자세한 내용은 다음 이슈에서 확인하실 수 있습니다.

호환성

Kotlin 1.4는 일부 코너 케이스에서 1.3과 역호환되지 않습니다. 이러한 사례는 언어 위원회에서 모두 신중하게 검토한 후 "호환성 가이드"에 목록을 나열합니다(이 양식과 유사). 현재 이 목록은 YouTrack에서 확인하실 수 있습니다.

사전 릴리스 노트

이전 버전과의 호환성은 사전 릴리스 버전에는 적용되지 않습니다. 기능 및 API는 후속 릴리스에서 변경될 수 있습니다. 최종 RC에 도달하면 사전 릴리스 버전에서 생성된 모든 2진 파일이 컴파일러에서 사용 금지되며 1.4Mx로 컴파일된 모든 파일을 다시 컴파일 해야 합니다.

최신 기능 사용 방법

언제나처럼 play.kotl.in에서 Kotlin을 온라인에서 사용해볼 수 있습니다.

IntelliJ IDEAAndroid Studio에서 Kotlin 플러그인을 1.4-M3 버전으로 업데이트할 수 있습니다. 업데이트 방법 보기

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

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

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

릴리스에 관한 세부 정보 및 호환되는 라이브러리 목록은 여기에 나와 있습니다.

여러분의 의견을 들려주세요

이슈 트래커에 버그 보고서를 보내주신 데 감사드립니다. 또한 최종 릴리스 전 모든 중요 이슈를 수정할 수 있도록 최선을 다하겠습니다.

언제든Kotlin Slack#eap channel에 참여하세요(여기에서 초대받기). 질문하고 토론에 참여하거나 새로운 테스트 버전 빌드에 관한 알림을 받아보세요.

Let’s Kotlin!

외부 기여자

이 릴리스에 포함된 Pull 요청을 제공해 주신 모든 외부 기여자께도 감사의 마음을 전합니다.

이 게시물은 Pavel Semyonov가 작성한 Kotlin 1.4-M3 is Out: Standard Library Changes를 번역한 글입니다.