JetBrains는 Kotlin 2.5.0에서 Companion Blocks와 Companion Extensions라는 두 가지 새로운 메커니즘을 테스트하고 있다. 이는 타입과 연결된 멤버를 정의하는 방식을 확장하고 서로 다른 Kotlin 플랫폼 간 상호 운용성을 개선하기 위한 것이다. 회사는 새로운 설계가 기존의 Companion Objects를 사용해서는 쉽게 이용할 수 없었던 프로그래밍 패턴을 열어 준다고 말한다.
새로운 메커니즘이 추가하는 것은 무엇인가?
타입과 연결된 멤버는 특정 객체 하나에 속하지 않는 상수, 도구, 생성 함수 등을 정의하는 데 사용된다. 예를 들어 영벡터를 나타내는 상수나 특정 각도에 따라 벡터를 생성하는 함수가 이에 해당한다. 이전에는 이러한 사용 방식이 Companion Objects에 의존했지만, 새로운 Companion Blocks를 사용하면 타입 자체 내부에서 정의하는 방식에 더 가까운 문법으로 이러한 멤버를 작성할 수 있다.
한편 Companion Extensions를 사용하면 개발자가 원본 코드를 소유하지 않은 경우에도, 그리고 해당 타입이 Java에서 왔거나 애초에 Companion Object를 포함하지 않는 경우에도 모든 클래스나 인터페이스에 연결된 멤버를 추가할 수 있다. 이는 외부 타입의 기본 정의를 수정하지 않고도 해당 타입을 확장할 수 있음을 의미한다.
컴파일과 호환성의 변화
새로운 메커니즘은 컴파일 전략에서 Companion Objects와 다르다. JVM 플랫폼에서는 Companion Blocks가 static 멤버로 컴파일되며, 이에 따라 다른 플랫폼의 정적 멤버와 동작이 더욱 가까워진다. JetBrains는 이것이 Kotlin Multiplatform에 도움이 될 수 있다고 본다. Companion Block에서 expect 멤버를 정의한 다음 static 멤버를 포함하는 Java 클래스를 사용해 이를 구현할 수 있기 때문이다.
그러나 기능은 아직 실험 단계다. Companion Blocks를 활성화하려면 -Xcompanion-blocks 옵션을 사용해야 하며, 블록과 확장을 함께 사용하려면 -Xcompanion-blocks-and-extensions 옵션이 필요하다.
실험적 사용의 제한
Companion Extensions를 사용하면 컴파일러가 시험판 바이너리 파일을 생성한다. 따라서 해당 기능이 공식적으로 안정화될 때까지는 다른 프로젝트나 라이브러리가 이러한 확장을 사용하는 라이브러리를 종속 항목으로 소비하지 못할 수 있다. Companion Blocks를 노출하는 경우에는 같은 제한이 적용되지 않지만, 이를 사용하는 사용자 역시 기능을 활성화해야 한다.
Companion Objects를 마이그레이션해야 하는가?
JetBrains는 즉시 마이그레이션할 것을 권장하지 않는다. Companion Objects는 여전히 Kotlin의 핵심 구성 요소이며, 이에 대한 완전한 지원이 보장된다. 대부분의 경우 새로운 코드에는 Companion Blocks가 선호되는 선택지가 될 수 있지만, Companion Object가 인터페이스를 구현해야 하는 경우처럼 특정 상황에서는 Companion Objects가 여전히 필요하다. Companion Objects는 완전한 클래스로 컴파일되기 때문이다.
실제로는 많은 경우 object라는 단어를 삭제하는 것만으로 Companion Block으로 전환할 수 있지만, 프로젝트와 이를 사용하는 모든 코드에는 재컴파일이 필요하다. JetBrains는 생태계의 일부 도구가 아직 새로운 문법을 처리할 준비가 되지 않았을 수 있다는 점도 경고한다.
이 발전이 중요한 이유는 무엇인가?
이 변화는 Kotlin Multiplatform 개발자와 라이브러리 작성자에게 중요하다. JVM과 다른 플랫폼에서 정적 멤버라는 개념 사이의 격차를 줄이려 하기 때문이다. 그러나 현재 실질적인 가치는 여전히 실험 단계와 빌드 도구, 라이브러리 및 편집기가 얼마나 빠르게 업데이트되는지에 달려 있다. 따라서 기능이 안정화되기 전에는 Companion Blocks를 대규모 마이그레이션의 안전한 기반으로 보기보다는, 시험하고 설계를 평가하는 용도로 사용하는 것이 적절해 보인다.