2021년 5월 5일
Kotlin 1.5.0은 새로운 언어 기능, 안정적인 IR 기반 JVM 컴파일러 백엔드, 성능 향상 및 실험적인 기능을 안정화하고 오래된 것들을 폐지하는 진화적인 변경 사항을 소개합니다.
릴리스 블로그 게시물에서 변경 사항 개요를 찾을 수도 있습니다.
언어 기능
Kotlin 1.5.0은 1.4.30에서 미리보기로 제시된 새로운 언어 기능의 안정 버전을 제공합니다:
- JVM 레코드 지원
- Sealed 인터페이스 및 Sealed 클래스 개선
- 인라인 클래스
이러한 기능의 자세한 설명은 이 블로그 게시물과 Kotlin 문서의 해당 페이지에서 확인할 수 있습니다.
JVM 레코드 지원
Java는 빠르게 발전하고 있으며 Kotlin이 이와 상호 운용성을 유지하도록 하기 위해 최신 기능 중 하나인 레코드 클래스를 지원하였습니다.
Kotlin의 JVM 레코드 지원은 양방향 상호 운용성을 포함합니다:
- Kotlin 코드에서는 Java 레코드 클래스를 일반적인 속성을 가진 일반적인 클래스처럼 사용할 수 있습니다.
- Java 코드에서 Kotlin 클래스를 레코드로 사용하려면 데이터 클래스로 만들고 @JvmRecord 주석을 표시하면 됩니다.
@JvmRecord
data class User(val name: String, val age: Int)
Kotlin에서 JVM 레코드 사용에 대해 더 알아보세요.
Sealed 인터페이스
이제 Kotlin 인터페이스에도 sealed 수정자를 사용할 수 있으며 이는 클래스에서 작동하는 방식과 동일하게 작동합니다: sealed 인터페이스의 모든 구현은 컴파일 시간에 알려져 있습니다.
sealed interface Polygon
예를 들어 완전한 when 표현식을 작성하기 위해 그 사실을 의존할 수 있습니다.
fun draw(polygon: Polygon) = when (polygon) {
is Rectangle -> // ...
is Triangle -> // ...
// else는 필요하지 않습니다 - 모든 가능한 구현이 포함되어 있습니다.
}
또한, sealed 인터페이스는 클래스가 하나 이상의 sealed 인터페이스를 직접 상속할 수 있도록 하므로 보다 유연한 제한된 클래스 계층 구조를 사용할 수 있습니다.
class FilledRectangle: Polygon, Fillable
패키지 전체 sealed 클래스 계층 구조
이제 sealed 클래스는 동일한 컴파일 단위 및 동일한 패키지의 모든 파일에 하위 클래스를 가질 수 있습니다. 이전에는 모든 하위 클래스가 동일한 파일에 나타나야 했습니다.
직계 하위 클래스는 최상위 또는 다른 이름을 가진 클래스, 인터페이스 또는 객체 내에 중첩될 수 있습니다.
sealed 클래스의 하위 클래스는 적절하게 정규화된 이름을 가져야 하며 지역 또는 익명 객체일 수 없습니다.
sealed 클래스 계층 구조에 대해 더 알아보세요.
인라인 클래스
인라인 클래스는 값만 보유하는 값 기반 클래스의 하위 집합입니다. 이들을 사용하여 메모리 할당을 사용하는 추가 오버헤드 없이 특정 유형의 값에 대한 래퍼로 사용할 수 있습니다.
인라인 클래스는 클래스 이름 앞에 값을 지정하여 선언할 수 있습니다.
value class Password(val s: String)
JVM 백엔드는 또한 특별한 @JvmInline 주석이 필요합니다.
@JvmInline
value class Password(val s: String)
인라인 수정자는 경고와 함께 현재 폐기되었습니다.
인라인 클래스에 대해 더 알아보세요.
Kotlin/JVM
Kotlin/JVM은 내부적인 개선과 사용자를 위한 여러 개선 사항을 받았습니다. 그 중 가장 주목할 만한 사항은 다음과 같습니다:
- 안정적인 JVM IR 백엔드
- 새로운 기본 JVM 타겟: 1.8
- invokedynamic를 통한 SAM 어댑터
- invokedynamic를 통한 람다
- @JvmDefault 및 이전 Xjvm-default 모드의 폐기
- 널 가능성 주석 처리 개선 사항
안정적인 JVM IR 백엔드
Kotlin/JVM 컴파일러를 위한 IR 기반 백엔드는 이제 안정적이며 기본적으로 활성화되어 있습니다.
Kotlin 1.4.0부터 IR 기반 백엔드의 초기 버전이 미리보기로 사용 가능하였으며, 이제 언어 버전 1.5의 기본값이 되었습니다. 이전 백엔드는 이전 언어 버전에 대해 기본값으로 계속 사용됩니다.
IR 백엔드의 이점 및 미래 개발에 대한 자세한 내용은 이 블로그 게시물에서 확인할 수 있습니다.
Kotlin 1.5.0에서 이전 백엔드를 사용해야 하는 경우 프로젝트 구성 파일에 다음 줄을 추가할 수 있습니다:
Gradle에서:
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions.useOldBackend = true
}
Maven에서:
<configuration>
<args>
<arg>-Xuse-old-backend</arg>
</args>
</configuration>
새로운 기본 JVM 타겟: 1.8
Kotlin/JVM 컴파일에 대한 기본 대상 버전은 이제 1.8입니다. 1.6 대상은 폐기되었습니다.
JVM 1.6 빌드가 필요한 경우 여전히 이 대상으로 전환할 수 있습니다. 방법은 다음과 같습니다:
invokedynamic를 통한 SAM 어댑터
Kotlin 1.5.0은 이제 SAM (Single Abstract Method) 변환을 컴파일할 때 동적 호출 (invokedynamic)을 사용합니다:
- SAM 유형이 Java 인터페이스인 경우 어떤 표현식이든 사용됩니다.
- SAM 유형이 Kotlin 함수 인터페이스인 경우 람다가 사용됩니다.
새로운 구현은 LambdaMetafactory.metafactory()를 사용하며 컴파일 중에 보조 래퍼 클래스가 더 이상 생성되지 않습니다. 이로 인해 애플리케이션의 JAR 크기가 줄어들어 JVM 시작 성능이 향상됩니다.
익명 클래스 생성을 기반으로 한 이전 구현 체계로 롤백하려면 컴파일러 옵션 -Xsam-conversions=class을 추가하세요.
Gradle, Maven 및 명령 줄 컴파일러에서 컴파일러 옵션을 추가하는 방법을 알아보세요.
invokedynamic를 통한 람다
평범한 Kotlin 람다를 invokedynamic로 컴파일하는 것은 실험적입니다. 언제든지 중단되거나 변경될 수 있습니다. 사용하려면 (아래의 자세한 내용 참조) 옵트인이 필요하며 평가 목적으로만 사용해야 합니다. 이에 대한 피드백을 YouTrack에서 주시면 감사하겠습니다.
Kotlin 1.5.0은 함수 인터페이스의 인스턴스로 변환되지 않는 평범한 Kotlin 람다를 동적 호출 (invokedynamic)으로 컴파일하는 실험적인 지원을 소개합니다. 이 구현은 일반 람다 컴파일에 비해 세 가지 제한 사항이 있습니다:
- invokedynamic로 컴파일된 람다는 직렬화할 수 없습니다.
- 이러한 람다를 toString()으로 호출하면 덜 가독성이 좋은 문자열 표현이 생성됩니다.
- 실험적인 reflect API는 LambdaMetafactory로 생성된 람다를 지원하지 않습니다.
이 기능을 시도하려면 -Xlambdas=indy 컴파일러 옵션을 추가하세요. YouTrack 티켓을 사용하여 이 기능에 대한 피드백을 공유해 주시면 감사하겠습니다.
Gradle, Maven 및 명령 줄 컴파일러에서 컴파일러 옵션을 추가하는 방법을 알아보세요.
@JvmDefault 및 이전 Xjvm-default 모드의 폐기
Kotlin 1.4.0 이전에는 @JvmDefault 주석과 함께 -Xjvm-default=enable 및 -Xjvm-default=compatibility 모드가 있었습니다. 이것들은 Kotlin 인터페이스의 특정하지 않은 멤버에 대한 JVM 기본 메서드를 생성하는 데 사용되었습니다.
Kotlin 1.4.0에서는 전체 프로젝트에 대한 기본 메서드 생성을 전환하는 새로운 Xjvm-default 모드가 소개되었습니다.
Kotlin 1.5.0에서는 @JvmDefault 및 이전 Xjvm-default 모드인 -Xjvm-default=enable 및 -Xjvm-default=compatibility를 폐기합니다.
Java 상호 운용에서 기본 메서드에 대한 자세한 내용을 알아보세요.
널 가능성 주석 처리 개선 사항
Kotlin은 Java에서 널 가능성 정보를 다루는 널 가능성 주석을 지원합니다. Kotlin 1.5.0은 이 기능에 대한 여러 가지 개선 사항을 소개합니다:
- 컴파일된 Java 라이브러리의 형식 인자에 대한 널 가능성 주석을 읽습니다. 이러한 라이브러리는 종속성으로 사용됩니다.
- TYPE_USE 대상에 대한 널 가능성 주석을 지원합니다. 이 대상은 다음과 같습니다:
- 배열
- 가변 길이 인자 (varargs)
- 필드
- 형식 매개변수 및 그 경계
- 기본 클래스 및 인터페이스의 형식 인자
- 널 가능성 주석이 형식에 적용 가능한 여러 대상을 가지고 있고 이 중 하나가 TYPE_USE인 경우, TYPE_USE가 우선됩니다. 예를 들어, @Nullable이 TYPE_USE와 METHOD 대상을 지원하는 경우 메서드 시그니처 @Nullable String[] f()는 호출 시 fun f(): Array<String?>! 가 됩니다.
이러한 새로 지원되는 경우에는 Kotlin에서 Java를 호출할 때 잘못된 형식 널 가능성을 사용하면 경고가 발생합니다. 이러한 경우에 엄격 모드를 활성화하려면 오류 보고를 사용하는 -Xtype-enhancement-improvements-strict-mode 컴파일러 옵션을 사용하세요.
널 안전성 및 플랫폼 형식에 대해 자세히 알아보세요.
Kotlin/Native
Kotlin/Native은 이제 더 뛰어나고 안정적입니다. 주목할만한 변경 사항은 다음과 같습니다:
- 성능 향상
- 메모리 누수 검사기 비활성화
성능 향상
1.5.0 버전에서 Kotlin/Native은 컴파일 및 실행 속도를 높이는 성능 향상 세트를 받습니다.
디버그 모드에서 컴파일러 캐시는 linuxX64 (리눅스 호스트에서만) 및 iosArm64 대상에서 지원됩니다. 컴파일러 캐시를 활성화하면 대부분의 디버그 컴파일이 훨씬 빨리 완료되며, 첫 번째 컴파일을 제외한 대부분이 빠릅니다. 측정 결과 테스트 프로젝트에서 약 200% 속도 향상이 있었습니다.
새로운 대상에 대해 컴파일러 캐시를 사용하려면 프로젝트의 gradle.properties에 다음 줄을 추가하여 옵트인하세요:
- linuxX64 대상의 경우: kotlin.native.cacheKind.linuxX64=static
- iosArm64 대상의 경우: kotlin.native.cacheKind.iosArm64=static
컴파일러 캐시를 활성화한 후 문제가 발생하는 경우, 이슈 트래커 YouTrack에 보고해 주세요.
다른 개선 사항은 Kotlin/Native 코드의 실행 속도를 높입니다:
- 간단한 속성 접근자는 인라인화됩니다.
- 문자열 리터럴에 대한 trimIndent()는 컴파일 중에 계산됩니다.
메모리 누수 검사기 비활성화
내장된 Kotlin/Native 메모리 누수 검사기가 기본적으로 비활성화되었습니다.
초기에는 내부 사용을 위해 설계되었으며, 모든 경우에 대한 누수를 찾을 수 있는 것이 아니라 일부 경우에만 가능합니다. 게다가 나중에 응용 프로그램 충돌을 일으킬 수 있는 문제가 있음이 밝혀졌습니다. 따라서 메모리 누수 검사기를 비활성화하기로 결정했습니다.
메모리 누수 검사기는 특정 경우에는 여전히 유용할 수 있습니다. 예를 들어 유닛 테스트와 같은 경우입니다. 이러한 경우에는 다음 코드 줄을 추가하여 활성화할 수 있습니다:
Platform.isMemoryLeakCheckerActive = true
애플리케이션 런타임에서 검사기를 활성화하는 것은 권장하지 않습니다.
Kotlin/JS
Kotlin/JS는 1.5.0에서 진화적인 변경 사항을 받고 있습니다. JS IR 컴파일러 백엔드를 안정화하기 위한 작업과 다른 업데이트를 제공하고 있습니다.
webpack 5로의 업그레이드
Kotlin/JS Gradle 플러그인은 이제 브라우저 대상에서 webpack 4 대신 webpack 5를 사용합니다. 이것은 호환되지 않는 변경 사항을 가져오는 큰 webpack 업그레이드입니다. 사용자 지정 webpack 구성을 사용 중이라면 webpack 5 릴리스 노트를 확인해야 합니다.
webpack을 사용하여 Kotlin/JS 프로젝트 번들링에 대해 더 알아보세요.
IR 컴파일러용 프레임워크 및 라이브러리
Kotlin/JS IR 컴파일러는 Alpha 단계에 있습니다. 나중에 호환되지 않게 변경될 수 있으며 수동으로 이전 작업이 필요할 수 있습니다. 이에 대한 피드백을 YouTrack에서 환영합니다.
Kotlin/JS 컴파일러용 IR 기반 백엔드 작업과 함께 우리는 라이브러리 저자들이 두 모드로 프로젝트를 빌드하도록 장려하고 돕습니다. 이렇게 하면 Kotlin/JS 컴파일러 양쪽에 대한 아티팩트를 생성할 수 있으므로 새 컴파일러를 위한 생태계를 확장할 수 있습니다.
IR 백엔드를 위해 이미 많은 잘 알려진 프레임워크와 라이브러리가 사용 가능합니다. 예를 들어 KVision, fritz2, doodle 등이 있습니다. 프로젝트에서 이러한 라이브러리를 사용 중이라면 IR 백엔드로 프로젝트를 빌드하고 가져오는 이점을 확인할 수 있습니다.
자체 라이브러리를 작성하는 경우 'both' 모드에서 컴파일하여 클라이언트가 새 컴파일러와 함께 사용할 수 있도록 하세요.
Kotlin Multiplatform
Kotlin 1.5.0에서 각 플랫폼에 대한 테스팅 의존성을 선택하는 것이 간소화되었으며 이제 Gradle 플러그인이 자동으로 처리합니다.
멀티플랫폼 프로젝트에서 캐릭터 카테고리를 가져오는 새로운 API가 사용 가능합니다.
표준 라이브러리
표준 라이브러리는 실험적인 부분을 안정화하고 새로운 기능을 추가하는 등 다양한 변경과 개선 사항을 받았습니다:
- 안정적인 부호 없는 정수 형식
- 안정적인 로케일 무관한 대문자/소문자 텍스트 API
- 안정적인 Char-to-integer 변환 API
- 안정적인 Path API
- 정수 나눗셈과 나머지 연산자
- Duration API 변경
- 멀티플랫폼 코드에서 캐릭터 카테고리를 가져오는 새로운 API
- 새로운 컬렉션 함수 firstNotNullOf()
- String?.toBoolean()의 엄격한 버전
표준 라이브러리 변경 사항에 대해 자세히 알아보려면 이 블로그 포스트를 참조하세요.
안정적인 부호 없는 정수 형식
UInt, ULong, UByte, UShort 부호 없는 정수 형식은 이제 안정적입니다. 이러한 형식에 대한 연산, 범위 및 진행도도 마찬가지입니다. 부호 없는 배열 및 그에 대한 연산은 여전히 베타 상태입니다.
부호 없는 정수 형식에 대해 자세히 알아보세요.
안정적인 로케일 무관한 대문자/소문자 변환 텍스트 API
이 릴리스에서는 대문자/소문자 변환을 위한 로케일 무관한 새로운 API가 제공됩니다. 이 API는 로케일에 민감한 toLowerCase(), toUpperCase(), capitalize(), decapitalize() API 함수 대안을 제공합니다. 새로운 API는 다른 로케일 설정으로 인한 오류를 피할 수 있도록 도와줍니다.
Kotlin 1.5.0에서는 다음과 같은 완전히 안정적인 대안을 제공합니다:
- 문자열 함수에 대한 이전 버전과 1.5.0 대안:
- 문자 함수에 대한 이전 버전과 1.5.0 대안:
Kotlin/JVM에서는 명시적 Locale 매개변수가 있는 대문자 변환 함수, 소문자 변환 함수 및 제목 케이스 변환 함수도 사용할 수 있습니다.
이전 API 함수는 폐지되었으며 향후 릴리스에서 제거될 예정입니다.
텍스트 처리 함수의 전체 변경 목록을 KEEP에서 확인하세요.
안정적인 char-to-integer 변환 API
Kotlin 1.5.0부터 새로운 char-to-code 및 char-to-digit 변환 함수가 안정적으로 사용 가능합니다. 이러한 함수는 종종 유사한 문자열-to-Int 변환과 혼동되던 현재 API 함수를 대체합니다.
새로운 API는 이러한 이름 혼동을 제거하여 코드 동작을 더 투명하고 명확하게 만듭니다.
이 릴리스에서는 Char 변환을 명확하게 지정된 함수 집합으로 분할한 다음과 같은 세트의 Char 변환을 소개합니다:
- Char의 정수 코드를 가져오거나 주어진 코드에서 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 표현으로 변환하는 Int 확장 함수:
fun Int.digitToChar(radix: Int): Char
이제는 폐지된 Number.toChar()를 포함한 이전 변환 API(모두 Int.toChar()를 제외한 것)와 Char를 숫자 형식으로 변환하기 위한 Char 확장 프로퍼티(예: Char.toInt())를 사용하지 않습니다.
char-to-integer 변환 API에 대해 자세히 알아보세요.
안정적인 Path API
java.nio.file.Path에 대한 확장을 포함하는 실험적인 Path API가 이제 안정적입니다.
// div (/) 연산자를 사용하여 경로 생성
val baseDir = Path("/base")
val subDir = baseDir / "subdirectory"
// 디렉토리의 파일 목록 나열
val kotlinFiles: List<Path> = Path("/home/user").listDirectoryEntries("*.kt")
정수 나눗셈과 나머지 연산자
표준 라이브러리에 모듈러 산술에 대한 새로운 연산이 추가되었습니다:
- floorDiv()는 바닥을 내림한 나눗셈의 결과를 반환합니다. 정수 형식에서 사용할 수 있습니다.
- mod()는 바닥을 내림한 나머지(모듈러)를 반환합니다. 모든 숫자 형식에서 사용할 수 있습니다.
이러한 연산은 기존의 정수 나눗셈 및 rem() 함수(또는 % 연산자)과 매우 유사해 보이지만 음수 숫자에 대해 다르게 작동합니다
- a.floorDiv(b)는 a /와 다르게 결과를 내림하여(더 낮은 정수 방향으로) 반환하며 /는 결과를 0에 더 가까운 정수로 버립니다.
- a.mod(b)는 a와 a.floorDiv(b) * b의 차이입니다. 이 값은 0일 수도 있고 b와 동일한 부호를 가질 수 있으며 a % b는 다른 부호를 가질 수 있습니다.
println("Floored division -5/3: ${(-5).floorDiv(3)}")
println( "Modulus: ${(-5).mod(3)}")
println("Truncated division -5/3: ${-5 / 3}")
println( "Remainder: ${-5 % 3}")
Duration API 변경
Duration API는 실험적입니다. 언제든지 폐지되거나 변경될 수 있습니다. 평가 목적으로만 사용하세요. YouTrack에서 피드백을 받아보겠습니다.
다양한 시간 단위로 지속 시간 양을 나타내는 데 사용되는 실험적인 Duration 클래스가 있습니다. 1.5.0에서 Duration API는 다음 변경 사항을 받았습니다:
- 더 나은 정밀도를 제공하기 위해 내부 값 표현이 Double 대신 Long을 사용합니다.
- Long을 사용하여 특정 시간 단위로 변환하는 새로운 API가 있습니다. Double 값을 사용하는 이전 API를 대체합니다. 예를 들어 Duration.inWholeMinutes는 Duration.inMinutes를 대체하고 Long으로 표현된 지속 시간의 값을 반환합니다.
- Duration.fromXXX 함수의 새로운 동반 객체 함수가 있습니다. 예를 들어 Duration.seconds(Int)는 정수 초 수를 나타내는 Duration 객체를 생성합니다. Int.seconds와 같은 이전 확장 프로퍼티는 이제 폐지되었습니다.
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@ExperimentalTime
fun main() {
//sampleStart
val duration = Duration.milliseconds(120000)
println("There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes")
//sampleEnd
}
멀티플랫폼 프로젝트에서 문자 카테고리를 가져오는 새로운 API
Kotlin 1.5.0은 멀티플랫폼 프로젝트에서 유니코드에 따른 문자 카테고리를 가져오는 새로운 API를 도입합니다. 다양한 플랫폼 및 공통 코드에서 이제 여러 함수를 사용할 수 있습니다.
문자가 문자 또는 숫자인지 확인하는 함수:
- Char.isDigit()
- Char.isLetter()
- Char.isLetterOrDigit()
val chars = listOf('a', '1', '+')
val (letterOrDigitList, notLetterOrDigitList) = chars.partition { it.isLetterOrDigit() }
println(letterOrDigitList) // [a, 1]
println(notLetterOrDigitList) // [+]
문자의 대소문자를 확인하는 함수:
- Char.isLowerCase()
- Char.isUpperCase()
- Char.isTitleCase()
val chars = listOf('Dž', 'Lj', 'Nj', 'Dz', '1', 'A', 'a', '+')
val (titleCases, notTitleCases) = chars.partition { it.isTitleCase() }
println(titleCases) // [Dž, Lj, Nj, Dz]
println(notTitleCases) // [1, A, a, +]
기타 일부 함수:
- Char.isDefined()
- Char.isISOControl()
Char.category 속성 및 해당 반환 유형인 enum class CharCategory는 이제 멀티플랫폼 프로젝트에서도 사용할 수 있습니다.
문자에 대한 자세한 내용을 알아보세요.
새로운 컬렉션 함수 firstNotNullOf()
새로운 firstNotNullOf()와 firstNotNullOfOrNull() 함수는 mapNotNull()와 first() 또는 firstOrNull()을 결합합니다. 이 함수들은 원래 컬렉션을 사용자 지정 선택기 함수로 매핑하고 첫 번째 null이 아닌 값을 반환합니다. 이러한 값이 없으면 firstNotNullOf()은 예외를 throw하고 firstNotNullOfOrNull()은 null을 반환합니다.
val data = listOf("Kotlin", "1.5")
println(data.firstNotNullOf(String::toDoubleOrNull))
println(data.firstNotNullOfOrNull(String::toIntOrNull))
String?.toBoolean()의 엄격한 버전
두 개의 새로운 함수는 기존의 String?.toBoolean()의 대소문자 구분 엄격한 버전을 도입합니다:
- String.toBooleanStrict()는 리터럴 true 및 false를 제외한 모든 입력에 대해 예외를 throw합니다.
- String.toBooleanStrictOrNull()은 리터럴 true 및 false를 제외한 모든 입력에 대해 null을 반환합니다.
println("true".toBooleanStrict())
println("1".toBooleanStrictOrNull())
// println("1".toBooleanStrict()) // Exception
kotlin-test 라이브러리
kotlin-test 라이브러리는 몇 가지 새로운 기능을 소개합니다:
- 다중 플랫폼 프로젝트에서 테스트 종속성 사용의 간소화
- Kotlin/JVM 소스 세트에 대한 테스팅 프레임워크의 자동 선택
- 어서션 함수 업데이트
다중 플랫폼 프로젝트에서 테스트 종속성 사용의 간소화
이제 kotlin-test 종속성을 사용하여 commonTest 소스 세트에서 테스트에 대한 종속성을 추가할 수 있으며, Gradle 플러그인은 각 테스트 소스 세트에 해당하는 플랫폼 종속성을 추론합니다:
- JVM 소스 세트에 대한 kotlin-test-junit, Kotlin/JVM 소스 세트의 테스팅 프레임워크 자동 선택 참조
- Kotlin/JS 소스 세트에 대한 kotlin-test-js
- 공통 소스 세트에 대한 kotlin-test-common 및 kotlin-test-annotations-common
- Kotlin/Native 소스 세트에 대한 별도의 아티팩트 필요 없음
또한 kotlin-test 종속성을 공유 또는 플랫폼별 소스 세트에서 사용할 수 있습니다.
명시적 종속성이 있는 기존 kotlin-test 설정은 Gradle 및 Maven에서 모두 작동합니다.
테스트 라이브러리에 종속성 설정에 대한 자세한 내용은 더 알아보세요.
Kotlin/JVM 소스 세트에 대한 테스팅 프레임워크의 자동 선택
Gradle 플러그인은 이제 테스팅 프레임워크를 자동으로 선택하고 종속성을 추가합니다. 필요한 것은 공통 소스 세트에서 kotlin-test 종속성을 추가하는 것뿐입니다.
기본적으로 Gradle은 JUnit 4를 사용합니다. 따라서 kotlin("test") 종속성은 JUnit 4에 대한 kotlin-test-junit 변형을 해결합니다:
kotlin {
sourceSets {
val commonTest by getting {
dependencies {
implementation(kotlin("test")) // JUnit 4에 대한 종속성을 가져옵니다.
}
}
}
}
테스트 작업에서 JUnit 5 또는 TestNG를 선택하려면 테스트 작업에서 useJUnitPlatform() 또는 useTestNG()를 호출하면 됩니다:
tasks {
test {
// TestNG 지원 활성화
useTestNG()
// or
// JUnit 5 지원 활성화
useJUnitPlatform()
}
}
프로젝트의 gradle.properties에 kotlin.test.infer.jvm.variant=false 라인을 추가하여 자동 테스팅 프레임워크 선택을 비활성화할 수 있습니다.
테스트 라이브러리에 종속성 설정에 대한 자세한 내용은 더 알아보세요.
어서션 함수 업데이트
이 릴리스에서는 새로운 어서션 함수를 포함하고 기존 함수를 개선합니다.
kotlin-test 라이브러리에는 이제 다음과 같은 기능이 있습니다:
- 값의 유형 확인
새로운 assertIs<T> 및 assertIsNot<T>를 사용하여 값의 유형을 확인할 수 있습니다:
@Test
fun testFunction() {
val s: Any = "test"
assertIs<String>(s) // 단언이 실패하면 s의 실제 유형을 언급하는 AssertionError 발생
// assertIs의 계약으로 인해 s.length를 출력할 수 있습니다
println("${s.length}")
}
유형 소거 때문에 이 assert 함수는 다음 예제에서 값이 List 유형인지 확인하고 특정 String 요소 유형인지 확인하지 않습니다: assertIs<List<String>>(value).
- 배열, 시퀀스 및 임의의 이터러블에 대한 컨테이너 내용 비교
구조적 동일성을 구현하지 않는 다른 컬렉션에 대한 내용을 비교하기 위한 새로운 오버로드된 assertContentEquals() 함수 집합이 있습니다:
@Test
fun test() {
val expectedArray = arrayOf(1, 2, 3)
val actualArray = Array(3) { it + 1 }
assertContentEquals(expectedArray, actualArray)
}
- Double 및 Float 숫자에 대한 새로운 assertEquals() 및 assertNotEquals() 오버로드
두 개의 Double 또는 Float 숫자를 절대 정확성으로 비교할 수 있게 해주는 assertEquals() 함수에 대한 새로운 오버로드가 있습니다. 정확성 값은 함수의 세 번째 매개변수로 지정됩니다:
@Test
fun test() {
val x = sin(PI)
// 정확성 매개변수
val tolerance = 0.000001
assertEquals(0.0, x, tolerance)
}
- 컬렉션 및 요소 내용을 확인하는 새로운 함수
컬렉션 또는 요소에 무언가를 포함하는지 확인할 수 있는 assertContains() 함수가 추가되었습니다. 이 함수는 Kotlin 컬렉션 및 contains() 연산자를 가진 요소(IntRange, String 등)와 함께 사용할 수 있습니다:
@Test
fun test() {
val sampleList = listOf<String>("sample", "sample2")
val sampleString = "sample"
assertContains(sampleList, sampleString) // 컬렉션에 요소 포함
assertContains(sampleString, "amp") // 문자열에 부분 문자열 포함
}
- assertTrue(), assertFalse(), expect() 함수는 이제 인라인입니다
이제 이 함수들을 인라인 함수로 사용할 수 있으므로 람다 표현식 내에서 suspend 함수를 호출할 수 있습니다:
@Test
fun test() = runBlocking<Unit> {
val deferred = async { "Kotlin is nice" }
assertTrue("Kotlin substring should be present") {
deferred.await() .contains("Kotlin")
}
}
kotlinx 라이브러리
Kotlin 1.5.0과 함께, 새로운 버전의 kotlinx 라이브러리가 출시되었습니다:
- kotlinx.coroutines 1.5.0-RC
- kotlinx.serialization 1.2.1
- kotlinx-datetime 0.2.0
Coroutines 1.5.0-RC
kotlinx.coroutines 1.5.0-RC는 다음과 같은 기능을 제공합니다:
- 새로운 채널 API
- 안정적인 반응형 통합
- 그 외 다양한 업데이트
Kotlin 1.5.0부터 실험적인 코루틴이 비활성화되었으며 -Xcoroutines=experimental 플래그는 더 이상 지원되지 않습니다.
변경 내용에 대한 자세한 내용은 변경 로그 및 kotlinx.coroutines 1.5.0 릴리스 블로그 포스트에서 확인할 수 있습니다.
Serialization 1.2.1
kotlinx.serialization 1.2.1은 다음과 같은 기능을 제공합니다:
- JSON 직렬화 성능 개선
- JSON 직렬화에서 여러 이름 지원
- @Serializable 클래스에서 .proto 스키마 생성에 대한 실험적 지원
- 그 밖에도 다양한 업데이트가 있습니다.
변경 내용에 대한 자세한 내용은 변경 로그 및 kotlinx.serialization 1.2.1 릴리스 블로그 포스트에서 확인할 수 있습니다.
dateTime 0.2.0
kotlinx-datetime 0.2.0은 다음과 같은 기능을 제공합니다:
- @Serializable Datetime 객체
- DateTimePeriod와 DatePeriod의 정규화된 API
- 그 밖에도 다양한 업데이트가 있습니다.
변경 내용에 대한 자세한 내용은 변경 로그 및 kotlinx-datetime 0.2.0 릴리스 블로그 포스트에서 확인할 수 있습니다.
Kotlin 1.5.0으로 마이그레이션
IntelliJ IDEA와 Android Studio는 Kotlin 플러그인을 1.5.0으로 업데이트하는 것을 제안할 것입니다.
기존 프로젝트를 Kotlin 1.5.0으로 마이그레이션하려면 Kotlin 버전을 1.5.0으로 변경하고 Gradle 또는 Maven 프로젝트를 다시 가져 오면 됩니다. Kotlin 1.5.0으로 업데이트하는 방법에 대해 자세히 알아보세요.
Kotlin 1.5.0으로 새 프로젝트를 시작하려면 Kotlin 플러그인을 업데이트하고 파일 | 새로 만들기 | 프로젝트에서 프로젝트 마법사를 실행하세요.
새로운 명령줄 컴파일러는 GitHub 릴리스 페이지에서 다운로드할 수 있습니다.
Kotlin 1.5.0은 기능 릴리스이며 언어와 호환되지 않는 변경 사항을 가져올 수 있습니다. Kotlin 1.5에 대한 호환성 가이드에서 자세한 변경 목록을 찾을 수 있습니다.
원문
https://kotlinlang.org/docs/whatsnew15.html#migrating-to-kotlin-1-5-0
'Kotlin > What's new' 카테고리의 다른 글
[Kotlin 번역] What's new in Kotlin 1.5.30 (2) | 2023.09.17 |
---|---|
[Kotlin 번역] What's new in Kotlin 1.5.20 (2) | 2023.09.16 |
[Kotlin 번역] What's new in Kotlin 1.4.30 (42) | 2023.09.16 |
[Kotlin 번역] What's new in Kotlin 1.4.20 (3) | 2023.09.16 |
[Kotlin 번역] What's new in Kotlin 1.4.0 (3) | 2023.09.16 |
댓글