2015년 9월 16일
이번 Kotlin M13 업데이트에 대한 내용입니다(자세한 내용은 아래에 나와 있습니다):
- 컴파일러 데몬을 통한 빠른 컴파일
- 의존성 주입 및 다른 프레임워크를 지원하기 위한 lateinit 프로퍼티
- 닫힌 계층을 표현하기 위한 sealed 클래스
- 어노테이션 대상 지정 및 확인
- Java의 get/set 쌍은 이제 Kotlin에서 프로퍼티로 인식됩니다
- Java 상호 운용성을 위한 더 나은 유형 안전성: @NotNull 어노테이션 고려(이 블로그 포스트 참조)
- 수정자와 어노테이션을 구문적으로 분리함(이 블로그 포스트 참조)
- 클래스, 함수 및 프로퍼티에 대한 완전한 기능적인 리플렉션
- 내부 접근은 이제 모듈 외부에서도 확인됨(아래 자세한 내용 참조)
- 최상위 함수 및 프로퍼티에 대한 새로운 .class 파일 레이아웃
- 기타(아래 자세한 내용 참조)
언어 변경 사항
언어를 마무리하고 구문을 최종화하며, 중요한 사용 사례에 부족한 부분을 추가하고 있습니다. 일부 변경 사항은 호환성이 없는 변경 사항이며, 보통 이러한 변경에 대한 이전 버전과의 호환성을 위해 최선을 다해 도와드립니다.
1.0 릴리스는 현재 JVM 지원에 중점을 두고 있습니다. JavaScript 백엔드도 포함되지만 실험적인 기능으로 간주될 것입니다. 따라서 이 릴리스에서 JavaScript에 영향을 미치는 변경 사항은 거의 없습니다. 1.0 릴리스 이후에는 JavaScript 작업을 계속할 계획입니다.
Late-init 프로퍼티
Kotlin을 Java 필드에 값을 주입하는 프레임워크(의존성 주입, 모의, 직렬화 및 기타 프레임워크)와 함께 사용할 때 가장 큰 문제 중 하나는 생성자에서 초기화되지 않은 빈 값의 프로퍼티를 가질 수 없다는 것이었습니다.
이제 우리는 lateinit 프로퍼티를 도입합니다:
class Example {
@Inject
lateinit val foo: Foo
@Inject
lateinit var bar: Bar
}
foo와 bar는 초기화 값이 없지만 동시에 널이 아닌 타입을 선언합니다. 초기화되기 전에 읽으려고 하면 예외가 발생하지만, DI 프레임워크(Guice, Dagger 또는 Spring)에서 초기화되면 일반적인 프로퍼티처럼 읽을 수 있습니다.
이러한 프로퍼티는 JUnit의 setUp 초기화와 같은 다른 사용 사례에도 사용할 수 있습니다. 참고로 val과 var 모두 lateinit으로 표시될 수 있습니다. var와 달리 코드에서 자유롭게 할당할 수는 없지만 프레임워크는 JVM 필드에 final로 표시되지 않기 때문에 장애 없이 값 주입을 할 수 있습니다.
자세한 내용은 언어 문서를 참조하십시오.
Sealed 클래스
많은 사람들이 Kotlin이 대수적 데이터 타입(ADT)을 지원하는지 묻습니다. 답은 항상 "네, ADT는 Kotlin에서 클래스로 표현할 수 있으며 when이 거의 패턴 매칭과 같을 정도로 좋다"였습니다. 이제 우리는 조금 더 유형 안전성을 추가했습니다: sealed 클래스를 사용하여 when에서 모든 경우가 나열되도록 할 수 있습니다:
package pets
import pets.Pet.*
sealed class Pet(val name: String) {
class Dog(name: String): Pet(name)
class Cat(name: String): Pet(name)
}
fun Pet.saySomething(): String {
return when (this) {
is Dog -> "woof"
is Cat -> "meow"
}
}
위의 예제에서 else는 필요하지 않습니다: Pet이 sealed 클래스이므로 컴파일러는 Dog와 Cat을 제외한 하위 클래스가 없음을 알고 있습니다. 따라서 모든 경우가 확인되었고 else가 필요하지 않습니다. 만약 어떤 경우를 놓치게 되면 컴파일러가 오류를 보고하고 그 부분을 다루라거나 else를 사용하라고 알려줍니다.
현재 sealed 클래스의 중첩된 클래스만 확장할 수 있지만 나중에 이 제한을 완화하고 동일한 소스 파일 내의 서브클래스를 허용할 계획입니다.
더 많은 세부 정보는 문서를 참조하십시오.
Annotations require “@”
수정자와 어노테이션은 M13에서 구문적으로 분리되었습니다(이 블로그 포스트 참조). 이제 어노테이션에 @가 필요하며, 모든 어노테이션 클래스는 대문자로 시작해야 합니다(이는 Java와의 일관성을 더 향상시킵니다).
따라서 @Throws와 같은 라이브러리 어노테이션 또는 @Volatile와 같은 어노테이션은 이름이 변경되었습니다. 또한 @platformName을 @JvmName으로, @platformStatic을 @JvmStatic으로 변경했습니다.
일부 이전의 어노테이션은 수정자로 변경되었습니다:
- data
- inline-related
1. inline
2. noinline
3. crossiniline — 이전의 @inlineOption(ONLY_LOCAL_RETURNS) 대신
- tailrec — 이전의 @tailRecursive 대신
- external — 이전의 @native 대신
이 변경은 대부분의 사용자에게는 투명합니다. 이름이 변경되지 않은 어노테이션은 이전부터 수정자처럼 보였기 때문입니다.
이전의 구문과 클래스는 폐기되었습니다.
코드 정리 IDE 작업은 코드를 마이그레이션하는 데 도움이 될 것입니다.
Annotation targets 및 기타 옵션
Kotlin은 이제 다음의 어노테이션 옵션(어노테이션 클래스에 어노테이션으로 표시된)을 지원합니다:
- @Retention – 어떤 범위에서 이 어노테이션을 볼 수 있는지: RUNTIME(기본값), BINARY(.class 파일 전용) 또는 SOURCE;
- @Target – 어노테이션이 적용 가능한 위치;
- @MustBeDocumented – 이 어노테이션이 주석된 요소의 API 일부임을 나타내는 표시기로, 생성된 문서에 표시되어야 합니다;
- @Repeatable – 이 어노테이션을 동일한 요소에 여러 번 사용할 수 있다는 표시기입니다.
더 많은 내용은 문서를 참조하십시오.
또한 이제 어노테이션에 선택적 대상을 사용 위치에 지정할 수 있습니다:
class Example(
@field:MyFieldAnnotation(...)
val foo: Foo
)
참고: 이것은 호환성이 없는 변경 사항입니다. M13 이전에는 기본 생성자의 매개 변수를 어노테이션으로 주석 처리할 때 어노테이션을 매개 변수와 해당하는 필드 양쪽에 모두 작성했습니다. 이제 해당 매개 변수, 프로퍼티 또는 필드 중 하나(첫 번째로 적용 가능한 대상)에만 작성됩니다. 즉, 필드 및 매개 변수 양쪽 모두에 적용 가능한 경우 이제 매개 변수에만 작성됩니다. 이는 Jackson을 사용할 때 몇 가지 문제를 일으킬 수 있지만 특별한 Jackson 모듈을 사용하면 쉽게 해결할 수 있습니다. 이전 방식은 이 기능이 없었습니다.
더 많은 정보는 문서를 참조하십시오.
가시성
접근 수정자/가시성 모델을 재검토했습니다. 이제부터:
- 최상위(어떤 클래스에도 속하지 않은)에서의 private는 "이 소스 파일 내에서만 볼 수 있음"을 의미합니다.
- 더 이상 public 선언에 대한 명시적 반환 유형이 필요하지 않습니다.
- 기본 가시성(수정자 없음)은 internal에서 public으로 변경되었습니다.
- 이제 내부 선언을 모듈 외부에서 사용하는 것을 거부하는 검사를 활성화했습니다.
이것은 기본 가시성으로 public을 선택한 것이 논란이 될 수 있습니다. Kotlin은 타입 안전한 언어이므로 가장 안전한 옵션인 private을 기본값으로 선택하는 것이 더 논리적일 수 있습니다. 물론 이러한 기본값에 대한 합당한 주장도 있습니다. 그러나 Kotlin은 실용적인 언어이기도 합니다.
코드 베이스에서 public/private 결정이 명시적으로 이루어지는 실제 Java 코드 베이스에서는 public이 매우 흔한 경우입니다(우리가 조사한 코드 베이스, Kotlin 컴파일러 및 IntelliJ IDEA를 포함한 코드 베이스에서 2.5~5배 정도 더 자주 발생함). 이는 Kotlin이 디자인을 구현하기 위해 사람들로 하여금 곳곳에 public을 작성하게 만들 것이며, Kotlin을 훨씬 더 절차적인 언어로 만들 것입니다. 우리의 경험에 따르면 명시적인 public은 많은 DSL 및 종종 기본 생성자의 흐름을 방해합니다. 그러므로 코드를 깔끔하게 유지하기 위해 기본값으로 public을 사용하기로 결정했습니다.
참고: internal은 여전히 지원되지만 이제 명시적으로 지정해야 합니다.
기타 변경 사항
- 오버로드된 호출 가능 참조를 지원합니다: foo가 오버로드되었더라도 컨텍스트에 따라 올바른 시그너처를 선택하여 ::foo를 사용할 수 있습니다.
- 모호하지 않은 super는 각진 괄호 없이 사용할 수 있습니다.
- 유형 매개 변수에 대한 엄격한 널 가능성 확인
- 기본 매개 변수가 없는 함수가 오버로드 해결에서 우선적으로 선택됩니다(API 진화에 유용)
- @HiddenDeclaration 어노테이션은 이제 선언을 숨기면서 이진 파일에는 유지하는 데 사용됩니다(더 원활한 API 진화를 위함).
자바 상호 운용 변경 사항
자바 get/set 쌍은 이제 프로퍼티로 간주됩니다
이 기능을 오랜 시간 동안 요청해 왔고, 이를 구현하는 데 시간이 걸렸습니다. 이제 자바 클래스를 사용할 때 관례에 따라 프로퍼티를 정의하는 경우 (예: getFoo() 및 setFoo()), Kotlin은 자동으로 해당 확장 프로퍼티를 정의합니다:
// Java:
class JBean {
public Foo getFoo() { return ...; }
public void setFoo(Foo foo) { ... }
}
// Kotlin
fun demo(bean: JBean) {
println(bean.foo) // 'foo'가 자동으로 정의됨
}
이러한 프로퍼티에 대한 액세스는 최적화되어 bean.foo가 중간 호출 없이 bean.getFoo()로 컴파일됩니다.
상위 선언의 .class 파일 새 레이아웃
몇 달 전에 이 변경 사항을 발표했고 이제 구현되었습니다:
- 기본적으로 각 Kotlin 소스 파일 (예: myFile.kt)은 같은 이름을 가진 클래스 파일을 생성합니다. 이 이름은 대문자로 변환되며 "Kt"로 접미됩니다: MyFileKt;
- 해당 파일에서 정의한 상위 함수 및 프로퍼티는 Java에서 이 클래스 이름을 통해 액세스할 수 있습니다(문제가 되는 FooPackage 대신);
- 따라서 동일한 패키지에 있는 두 파일은 같은 이름을 가질 수 없습니다(또는 클래스 파일이 충돌할 것입니다);
- 클래스의 이름을 변경하려면 @file:JvmName("CustomName") 주석을 소스 파일에 지정할 수 있습니다;
- 많은 파일이 동일한 JVM 이름을 공유할 수 있도록 @file:JvmMultifileClass 주석으로 표시된 경우입니다.
이 변경 사항을 사용하려면 Kotlin 바이너리와 Kotlin 코드를 컴파일하기 위해 필요한 새로운 리소스 파일을 도입했습니다. 이 파일의 이름은 META-INF/<module_name>.kotlin_module입니다. 이러한 .kotlin_module 파일이 포장 프로세스에 의해 제거되지 않도록 하십시오. 또한 프로젝트에서 모듈 이름이 충돌하지 않도록 하십시오:
- Maven에서는 groupId와 artifactId를 모듈 이름으로 사용합니다. 사용자 지정하려면 다음과 같이 설정할 수 있습니다:
<configuration>
<moduleName>com.example.mymodule</moduleName>
</configuration>
- Gradle에서는 프로젝트 이름 + build 작업 이름을 사용합니다. 사용자 지정하려면 다음과 같이 설정합니다:
compileKotlin {
kotlinOptions.moduleName = "com.example.mymodule"
}
- Ant 및 명령 줄에서는 모듈 이름을 명시적으로 지정해야 합니다:
<kotlinc modulename="com.example.mymodule"/>
$ kotlinc-jvm -module-name com.example.mymodule
자바 상호 운용에서의 Null 안전성
우리는 이전에 이것을 발표했습니다. 이제 @NotNull 및 @Nullable을 Java에서 사용하고 Kotlin이 이를 인식하여 잘못된 사용이 경고가 아닌 컴파일 오류로 결과됩니다.
결과적으로 Java 컬렉션 사용이 훨씬 더 안전해졌습니다. 이제 더 이상 ArrayList<String>에 null을 넣을 수 없습니다.
플랫폼 유형은 그대로 유지됩니다. 왜냐하면 주석이 종종 누락되거나 때로는 잘못되기 때문입니다(상속 규칙을 위반할 수 있음). 따라서 기본적으로 Java 코드에 정적인 null 체크가 부과되지 않습니다.
외부 주석도 사용되지 않으므로 많은 빌드 구성이 생략되었습니다.
라이브러리
Kotlin 라이브러리도 활발히 개발 중입니다. M13은 클래스, 멤버, 매개 변수 등을 조사할 수 있는 완전한 기능을 갖춘 리플렉션 라이브러리를 제공합니다. 관련된 별도의 블로그 게시물이 곧 나올 예정입니다.
표준 라이브러리에는 다음과 같은 편리한 추가 기능이 포함되어 있습니다:
- 집합 및 기타 컬렉션을 위한 + 및 -;
- 프로퍼티를 위한 개선된 대리자.
이에 대한 자세한 내용은 별도의 게시물에서 다룰 예정입니다.
도구
컴파일러 데몬. 이전에 Gradle 데몬을 지원한다고 발표하였고 여러분의 피드백은 긍정적이었습니다: 컴파일 시간이 최대 3배까지 줄어듭니다. 컴파일 성능을 계속 개선하고 있으며, M13부터는 IntelliJ IDEA에서도 Gradle과 유사한 데몬을 사용합니다. 이 기능은 현재 "실험적"으로 표시되어 있으므로 활성화하려면 환경 설정 대화 상자에서 해당 확인란을 선택해야 합니다:
Build, execution, deployment -> Compiler -> Kotlin compiler -> Keep compiler process alive between invocations (experimental)
증분 컴파일은 Kotlin 컴파일 시간을 개선하기 위해 취한 또 다른 방향입니다. M13에서는 다음과 같은 기능을 제공합니다:
- 인라인 함수에 대한 증분 컴파일: 이제 인라인 함수의 내용을 변경하면 해당 함수를 사용하는 클래스만 다시 컴파일됩니다.
- 비공개 멤버의 변경이 다른 파일의 재컴파일을 유발하지 않습니다.
IDE
IDE 경험도 개선되었습니다. 간결함을 위해 쉽게 발견하기 어려운 기능만 강조합니다:
- IDE는 매개 변수의 이름과 유형을 입력할 때 제안합니다:
(힌트: 이미지 위에 마우스를 올려 애니메이션을 시작하려면 마우스를 올리세요)
- 위에서 언급한대로 우리는 Java의 get/set 쌍 대신에 합성 프로퍼티를 도입했습니다. 그러나 여전히 Java 마인드일 수 있으며 프로퍼티 이름 대신 "get"을 입력하기 시작할 수 있습니다. 따라서 완성 기능은 이러한 경우에 프로퍼티를 제안합니다.
- 어떤 컬렉션을 반복하려면 그 이름을 입력하고 특별한 의도 동작으로 이를 for 루프로 변환할 수 있습니다:
- 다른 의도 동작으로 for 루프에 인덱스를 추가/제거할 수 있습니다:
- 명명된 인수는 코드 가독성을 크게 향상시킬 수 있습니다. Kotlin IDE는 이제 인수를 명명된 형식으로 전환하거나 다시 되돌릴 수 있는 작업을 제공합니다:
- 사용하지 않는 import의 하이라이팅도 지원됩니다. 그리고 옵션을 설정하여 import를 최적화하는 옵션도 설정할 수 있습니다:
- 디버거는 이제 람다 표현식에 대한 스마트 스텝 인투 (⇧F7)를 지원하며 현재 실행 중인 람다 표현식을 하이라이팅합니다.
참고: 이 기능은 IntelliJ IDEA 15 EAP (버전 142.4465 이상)에서만 사용 가능하며 비인라인 람다 표현식에 대해서만 적용됩니다.
- 디버거는 인라인 함수에 대한 Step Over (F8) 및 Step Out (⇧F8)를 제공하며 Evaluate Expressions 내에서 함수 내의 모든 로컬 변수를 사용할 수 있습니다.
- Java2Kotlin 변환기는 이제 Java 8 메서드 참조를 지원합니다.
- Pull Members Up/Down을 위한 리팩토링 지원
- main(..), 테스트 등과 같은 실행 가능한 항목은 런 구성을 표시하는 거터 아이콘으로 표시되며 팝업 메뉴를 통해 실행 구성을 볼 수 있습니다 (IntelliJ IDEA 15 EAP 전용)
설치
IntelliJ IDEA 14.1에서는 플러그인 관리자를 통해 플러그인을 업데이트하면 됩니다(평소와 같이).
IntelliJ IDEA 15 EAP에서는 Kotlin M12가 번들로 제공되므로 M13으로 업데이트하려면 다음을 수행해야 합니다.
- 플러그인 zip 파일을 다운로드합니다.
- 환경 설정 -> 플러그인으로 이동하고 디스크에서 플러그인 설치...를 선택하여 설치합니다.
- IDE를 다시 시작하십시오.
다음 IntelliJ IDEA EAP에서 업데이트 프로세스를 더 원활하게 만들 계획입니다.
기존 컴파일러는 여기에서 찾을 수 있습니다.
좋은 Kotlin 사용하세요!
원문
https://blog.jetbrains.com/kotlin/2015/09/kotlin-m13-is-out/
'Kotlin > Release Notes' 카테고리의 다른 글
[Kotlin Release Notes] Kotlin M14 is out! (0) | 2023.08.28 |
---|---|
[Kotlin Release Notes] Kotlin Eclipse Plugin 0.3.0 (1) | 2023.08.28 |
[Kotlin Release Notes] Kotlin M12 is out! (0) | 2023.08.28 |
[Kotlin Release Notes] Kotlin M11 is Out! (0) | 2023.08.28 |
[Kotlin Release Notes] M10 is out (0) | 2023.08.28 |
댓글