2014년 10월 15일
M9가 도착했고 많은 새로운 기능과 중요한 변경 사항을 가져왔습니다. 우리는 이미 이를 강조하고 다른 몇 가지 개선 사항에 대해서도 자세히 다루었습니다. 이제 몇 가지 다른 개선 사항에 대해 더 자세히 알아보겠습니다.
언어 변경
참고: 아래의 변경 사항 중 일부는 호환성이 없는 변경 사항입니다. 이는 이전 버전에서 컴파일 가능했던 일부 코드가 더 이상 컴파일되지 않을 수 있음을 의미하므로 수정해야 합니다.
플랫폼 타입
우리가 이전에 언급한 대로, 플랫폼 상호 운용성 (즉, Java 및 JavaScript 상호 운용성)은 사용자들을 위해 가장 중요한 우선 순위 중 하나입니다. Java와 상호 운용할 때의 Null 가능성 문제는 가장 큰 불만 중 하나였습니다. 요약하자면, Java에서 온 어떤 참조도 null일 수 있으며, Kotlin은 설계상으로 null 안전성을 가지고 있기 때문에 사용자는 Java 값을 사용할 때마다 null 체크를 해야 했거나 안전한 호출 (?.) 또는 not-null 단언문 (!!)을 사용해야 했습니다. 이러한 기능들은 순수한 Kotlin 환경에서 매우 편리하지만, Kotlin/Java 설정에서 너무 자주 사용해야 하는 경우에는 재앙으로 바뀔 수 있습니다. 우리는 외부 주석과 KAnnotator에 의존하여 Java에 추가적인 유형 정보를 제공함으로써 이 문제를 완화시키는 방식을 채택했습니다. 그러나 이 접근 방식은 지나치게 번거로우며 일부 경우에는 작동하지 않습니다.
그래서 우리는 급진적인 방법을 택하고 Kotlin의 유형 시스템을 Java 상호 운용성에 더 유연하게 만들었습니다. 이제 Java에서 온 참조는 특별히 표시된 유형을 갖게 되었는데, 이를 "플랫폼 유형"이라고 부릅니다. 이 플랫폼 유형은 다음과 같이 특별하게 처리됩니다.
- Kotlin은 플랫폼 유형에 대해 null 안전성을 강제하지 않습니다. 즉, Java 값에 대해서는 Java의 의미론이 적용됩니다. 이제 Java에서 온 값에 대해 NPE가 발생할 수 있습니다.
val s = javaMethod() // s는 플랫폼 유형을 갖습니다.
s.foo() // 이 줄은 Java와 같이 NPE를 던질 수 있습니다.
- 플랫폼 유형은 Kotlin 코드에서 명시적으로 언급될 수 없지만, IDE/컴파일러에서 유형 정보를 표시할 때 느낌표로 끝나는 것으로 구분됩니다. 예: String!, ArrayList<Int!>!, (Mutable)Collection<Foo!>!.
- 플랫폼 값을 저장할 때 유형 추론을 의존하거나 Kotlin 유형을 선택할 수 있습니다 (원하는 대로 nullable 또는 not-null):
val s = javaMethod() // 플랫폼 유형 추론됨
val s1: String = javaMethod() // 프로그래머가 선택한 not-null 유형
val s2: String? = javaMethod() // 프로그래머가 선택한 nullable 유형
플랫폼 값을 not-null 유형에 할당할 때 Kotlin은 바이트 코드에 단언문을 생성하여 non-null 변수가 null을 포함하지 않도록 하여 대부분의 null이 코드를 통해 전파되는 것을 막습니다. 따라서 이 예제에서는 2번째 줄에 단언문 오류가 발생할 수 있으며, 나중에 NPE가 발생할 가능성이 있습니다.
- Java 메서드를 재정의할 때도 플랫폼 유형을 명시적으로 언급할 수 없으므로 Kotlin 유형을 선택해야 합니다:
class KotlinClass : JavaClass() {
// Java에서 'List javaMethod(String s)'로 선언됨
override fun javaMethod(p1: String): List { ... }
// 또는 다음과 같을 수 있습니다
override fun javaMethod(p1: String?): MutableList?
// 또는 다양한 null 가능성 및 컬렉션 가변성의 조합일 수 있습니다
}
요약하면, 플랫폼 유형은 Java에서 온 항목의 경우 Kotlin의 유형 시스템을 더 유연하게 만듭니다. Java 라이브러리를 사용하는 경우 Kotlin은 Java와 동일하게 안전합니다. Java가 포함되지 않은 경우 Kotlin은 더욱 안전하며 NullPointerException이 발생하지 않도록 보장합니다. 미래에는 플랫폼 유형에 대한 진단을 개선하여 Kotlin이 Java 상호 운용성 사례에서 null 오용에 대한 경고를 출력할 계획입
니다.
Platform Interop에 대한 더 많은 내용
더 나은 플랫폼 상호 운용성을 위해 도입된 변경 사항에 대해서 이미 자세히 다루었지만, 간단히 요약하자면, Java에서 호출될 때 메서드를 정적으로 정의하기 위해 platformStatic 주석을 도입하였으며, 더 나은 getter, setter 및 기타 상호 운용 측면을 다루기 위한 일련의 개선 사항을 도입하였습니다.
더 이상 지역 객체 선언 불가능
M9 버전부터 명명된 객체는 더 이상 지역적으로 선언될 수 없습니다. 함수 내에서 객체를 사용하려면 객체 표현식을 사용해야 합니다. 즉, 이름 없는 객체를 변수에 할당하는 것입니다:
fun usingObjects() {
val configuration = object {
val maxRows = 10
}
}
이것은 Kotlin의 명명된 객체가 싱글톤을 나타내기 위한 것이기 때문입니다. 여러 번 호출될 수 있는 함수 내에 이러한 객체를 가지고 있는 것은 별 의미가 없습니다. 명명된 객체는 여전히 전역적이거나 비내부 클래스에 중첩된 경우에는 존재할 수 있습니다.
비지역 반환
고차 인라인 함수를 사용할 때 이제 비지역 반환을 수행할 수 있습니다:
inline fun using(closeable : Closeable, body : ()->Unit) {
try {
body()
} finally {
closeable.close()
}
}
fun processStream(stream : InputStream) {
using(stream) {
if (stream.read() == 42)
return // processStream을 종료함
}
}
using에 전달되는 함수 내에서 return을 호출하면 외부 함수인 processStream이 종료됩니다. processStream의 반환 유형이 Unit과 다른 경우, return은 값을 제공해야 합니다.
type은 더 이상 키워드가 아님
이제 type이라는 단어를 식별자로 사용할 수 있습니다. 이제 type은 더 이상 키워드가 아닙니다.
Unit은 이제 명명된 객체
이전에 Unit.VALUE로 불렸던 것은 이제 단순히 Unit으로 불립니다.
Foo.instance$는 Foo.INSTANCE$로 변경됨
Kotlin의 싱글톤(명명된 객체)에 접근하던 Java 코드에서 Foo.instance$로 접근하던 것은 이제 Foo.INSTANCE$입니다.
클래스 객체에 대해서도 동일하게 적용됩니다: 이전에는 C.object$였지만 이제 C.OBJECT$입니다.
증분 빌드
Kotlin의 목표는 항상 Java만큼 빠르게 동작하는 것이었으며, 아직 그 목표에 도달하지는 못했지만, 우리는 큰 한 걸음을 내딛었습니다. 이것은 증분 빌드를 제공하는 것입니다. IntelliJ IDEA에서는 Kotlin 컴파일러 옵션 아래의 확인란을 통해 이 옵션을 토글할 수 있습니다:
이 기능은 실험적인 기능임을 유의하세요. 제대로 작동하지 않는 경우 Rebuild Project를 실행하세요. 버그 리포트는 환영합니다.
또한 컴파일러 옵션 아래에서 프로젝트를 자동으로 만들도록 활성화할 수도 있습니다:
JavaScript 지원
우리는 JavaScript 백엔드에 많은 노력을 기울이고, 언어 문제를 해결하고 표준 라이브러리를 Java와 동등한 수준으로 업그레이드하려고 노력해 왔습니다 (가능한 한). 따라서 다음과 같은 코드는 이제 JavaScript를 대상으로 할 때 작동합니다:
val cars = listOf("Ford", "Audi", "Skoda", "Toyota", "Jeep")
cars.filter { it.contains("o") }
cars.forEach {
println(it)
}
표준 라이브러리를 개선하는 것 외에도 언어 지원을 개선하였으며, 이제 다음과 같은 것이 가능합니다:
- 위임 (class Foo : Bar by baz)
- 함수 및 프로퍼티에 대한 호출 가능한 참조 (::foo)
- Long에 대한 지원 및 Char 유형에 대한 개선된 지원
- 인라인 함수 지원
- 다중 catch 블록
또한 몇 가지 호환성이 없는 변경 사항이 있었습니다. 구체적으로 다음과 같습니다:
- Native 트레이트는 컴파일 시간에만 존재합니다.
- 함수 이름 맹글링에 일부 변경 사항이 있습니다.
- 일부 패키지의 이동 및 이름 변경이 있었습니다.
1. js.*는 이제 kotlin.js.*로 변경되었습니다.
2. js.query.*는 이제 jquery.*로 변경되었습니다.
3. js.debug.*는 이제 kotlin.js.*로 변경되었습니다.
- println() 동작에 변경 사항이 있었습니다:
1. node.js의 경우 - stdout에 쓰기
2. 그 외 (브라우저에서) - 버퍼링된 쓰기로 console.log에 출력하고 "\n"일 때 버퍼를 비웁니다.
JavaScript에 대한 더 자세한 내용은 별도로 다루겠습니다.
IntelliJ IDEA 개선 사항
IntelliJ IDEA용 Kotlin 플러그인에도 몇 가지 새로운 기능과 개선 사항이 있습니다.
함수 추출 리팩터링 및 코드 중복
이제 함수 추출은 코드 중복을 감지하여 유사한 코드를 추출한 함수로 대체할 수 있음을 제공합니다.
이렇게 하면 우리가 방금 추출한 함수로 유사한 코드 발생을 대체하도록 유도합니다.
사용에서 함수 생성
오랫동안 기다려온 Create From Usage 의도는 특히 때때로 TDD를 하는 사람들에게 유용합니다. 이제 우리는 사용을 기반으로 함수를 생성하고 확장 함수까지 생성할 수 있습니다.
모듈
최근까지 Kotlin은 모든 모듈의 심볼 또는 프로젝트의 어디에서나 참조된 라이브러리를 프로젝트 전체에 표시할 수 있는 것으로 처리했습니다. 예를 들어, 다음과 같은 세 개의 모듈이 있다면:
- 주문(Ordering)
- 청구(Invoicing)
- 배송(Shipping)
청구(Invoicing)와 배송(Shipping)은 주문(Ordering)에 의존하지만 서로에 의존하지 않습니다. 그러나 이제 M9 버전에서 IDE 내에서 완성 및 자동 가져오기는 모든 모듈의 심볼을 모든 모듈에서 보여주지 않게 됩니다. M9 버전부터는 의존하는 모듈에서만 심볼이 표시됩니다.
명명 규칙을 사용한 찾기 및 이름 바꾸기
Kotlin은 연산자 오버로딩을 허용합니다. 예를 들어, 우리는 +를 오버로딩하기 위해 plus라는 이름의 함수를 생성할 수 있습니다. 이제 이러한 이름을 바꿀 때 IntelliJ IDEA는 자동으로 해당 사용들을 모두 바꿔줍니다.
람다 표현식에서 명시적 인수로 이동할 때도 유사한 일이 발생합니다.
다른 IDE 개선 사항
또한 몇 가지 다른 개선 사항이 있습니다. 특히 다음과 같은 사항들이 있습니다.
- 디버거. 이제 위임된 프로퍼티를 지원합니다.
- 완성. 호출 지점에서 예상 유형이 알려진 경우 완성을 위한 전반적인 개선 사항
- 선택 확장. 현재 Java에 대한 모든 기능을 거의 모두 제공합니다.
- Java에서 Kotlin으로 변환. 더 많은 변환 시나리오를 지원합니다.
또한 많은 버그 수정이 이루어졌습니다.
Command line interface 변경 사항
명령 줄 컴파일러에도 몇 가지 변경 사항이 있어 더 간단해졌습니다. 이제 -src/-sourceFiles 매개변수를 지정할 필요가 없고, 단순히 옵션을 먼저 전달한 다음 소스 파일을 전달하면 됩니다:
kotlinc-jvm
-output 및 -jar와 같은 몇 가지 옵션이 변경되었습니다. 다음을 실행하면 모든 옵션을 확인할 수 있습니다:
kotlinc-jvm --help
또한 일부 고급 설정은 -X 매개변수 아래에 숨겨졌습니다. 다음을 실행하여 이 설정을 얻을 수 있습니다:
kotlinc-jvm -X
마지막으로 출력의 일부를 개선하여 상대 경로와 절대 경로를 나타내도록 꾸몄습니다.
JVM 코드 생성 및 성능 개선
이전에 언급한 대로, JVM에 대한 코드 생성을 개선하고 생성된 코드의 바이트 크기를 줄이고 성능을 향상시키는 작업도 진행하였습니다.
API 문서
Kotlin 자체뿐만 아니라 이전 API 참조 문서도 마크다운을 사용하는 완전히 새로운 형식으로 전환하는 작업을 진행했습니다.
새로운 사이트에서 API 참조를 찾을 수 있습니다.
요약
M9는 주로 플랫폼 유형 때문에 중요한 이정표입니다. 이 변경 사항이 올바른 방향으로 진행되고 상호 운용성을 더 쉽게 만드는지 여부를 결정하기 위해 피드백을 받는 것이 정말 중요합니다. 그러니 테스트해보고 의견을 알려주시기 바랍니다.
M9를 설치하려면 IntelliJ IDEA 13.1 또는 14 EAP에서 플러그인을 업데이트하면 되며, 항상 플러그인 저장소에서 플러그인을 찾을 수 있습니다.
참고: IDE의 캐시를 무효화하거나 프로젝트를 다시 빌드해야 할 수도 있습니다.
릴리스 페이지를 확인하시고 언제나 피드백을 환영합니다!
원문
'Kotlin > Release Notes' 카테고리의 다른 글
[Kotlin Release Notes] Kotlin M11 is Out! (0) | 2023.08.28 |
---|---|
[Kotlin Release Notes] M10 is out (0) | 2023.08.28 |
[Kotlin Release Notes] M9 is coming (0) | 2023.08.28 |
[Kotlin Release Notes] M8 is out! (0) | 2023.08.28 |
[Kotlin Release Notes] M7 Release Available (0) | 2023.08.28 |
댓글