[Kotlin] 장점, 단점, 그리고 아쉬운 점 이야기 |
https://medium.com/keepsafe-engineering/lessons-from-converting-an-app-to-100-kotlin-68984a05dcb6
https://medium.com/keepsafe-engineering/kotlin-the-good-the-bad-and-the-ugly-bf5f09b87e6f
-
위 링크의 글을 쓴 필자는 마켓에 출시된 Java 로 되어 있는 앱을 Kotlin 으로 전환했다.
많은 사람들이 Kotlin lib 때문에 dex method limit 이 걸릴 것을 걱정하지만,
실제 converting 후 proguard 적용시 method count 는 10% 줄어들고, code line 은 30% 줄어들었다.
( 5491 to 4987 & 12,371 to 8,564 )
돼지왕왕돼지 주 : proguard 적용 전에는 확실히 dex method limit 에 부딪힐수도 있겠다….
잘 다뤄지지 않는 장점
Java to Kotlin 자동 변환
perfect 하게 되진 않지만 그래도 초심자에게는 충분한 idea 를 준다.
그리고 기존 코드를 converting 할 시에는 (받아쓰기같은 느낌의) 불필요한 코딩도 많이 줄일 수 있다.
lateinit, Delegates.notNull and lazy
lateinit 덕에 android 의 onCreate 에서 view initialize 하는 경우, member 변수를 nullable 로 두지 않아도 된다.
lateinit 을 delegate 에 사용하는 경우에는 Delegates.notNull<Int>() 를 사용하면 된다.
lateinit 은 구조상 lazy init 이라면, 실제 lazy init 에서는 by lazy 함수를 사용할 수 있다.
Functional collection extensions
any, joinToString, associate 등을 사용하면 정말 많은 불필요한 코드를 줄일 수 있다.
( any 는 entry 가 있는지 여부, associate 는 collection 값을 기준으로 pair list 를 생성 )
Named and default function arguments
불필요한 overloading 정의를 막아준다.
잘 다뤄지지 않은 단점
No namespace
Kotlin 은 top level function, property 를 지원한다.
매우 편리하지만 헛갈릴 수 있다. ( 예 : 여러 파일에서 동명의 top level 함수 정의 )
Kotlin 내부에서 qualifier 없이 바로 쓸 수 있기 때문이다.
이에 대한 해결책은 사용시 qualifier 를 사용하는 방법인데 코드 가독성이 나뻐진다.
다른 방법은 top-level 대신 object 를 사용해서 singleton 으로 만드는 것이다. 이는 Java 에서 부를 때 INSTANCE 가 붙어 또한 ugly 하다. 이를 피하려면 @JvmStatic 으로 선언해야 하는데 이 또한 ugly 하다.
No static modifier
static 이 없어짐으로 인해서 Java 에서 호출할 때 쓸데없이 코드가 길어지고 가독성이 떨어질 수 있다.
기본적으로 무조건 getter 접근하게 되어서 예를 들어 View class 의 VISIBLE const 를 접근하려면 View.Companion.getVISIBLE() 로 접근하거나, @JvmField 를 주어 View.VISIBLE 로 접근해야 한다. 여튼 기대보다 번잡스럽다.
Java to Kotlin 자동 변환
장점이기도 하지만, 약 80% 정도만 제대로 작동한다.
Javadoc 은 가끔 완전 이상하게 노출되기도 한다. 특히 line wrap 이 있을 때.
static field 는 companion object 로 바뀌는데 기존 호출부를 다 고쳐야 한다. ( @JvmField, @JvmStatic 을 붙여주면 괜찮지만.. )
Required property accessor syntax
get 을 property 이름으로 갖고 있다면 lint 관련해서 문제가 되며, 이를 해결하기 위해서는 @Suppress(“UsePropertyAccessSyntax”) 를 싸줘야 한다.
Method count
line 수는 확실히 줄어들 것이다.
그러나 프로젝트에 따라 method count 는 늘어날 수 있다. 그래서 dex method count limit 에 도달할 수 있다.
method 가 늘어나는 이유는 여러가지가 있다.
우선 쉽게 생각할 수 있는 것은 Kotlin runtime 에 추가된 함수들
두번째는 property 의 등장으로 그들에 대한 자동 생성되는 get, set function 들
( private property with default getter & setter case 에는 실제 getter, setter 를 만들지 않는다 )
getter, setter 에 의해 method count limit 에 도달할 상황이면 @JvmField 를 적용하는 것도 한 방법이다.
아쉬운 점 ( Ugly 한 점 )
SAM conversion 과 lambda 의 Unit return
SAM interface 를 param 으로 받는 Java 함수가 있을 때는 큰 문제가 없다. Lambda 를 써주면 된다.
그러나 반대로 SAM interface 를 param 으로 받는 Kotlin 함수가 있을 때는 쉽지 않다..
fun registerCallback(r: View.OnClickListener)
registerCallback(View.OnClickListener { /* do something */ })
저렇게 안 하려면 함수 정의를 다르게 해야 한다.
그럼 Kotlin 에서는 OK 지만.. Java 에서는 Unit 을 return 해줘야 한다..
/* Kotlin */
fun registerCallback(r: () -> Unit)
/* Java */
registerCallback( () -> {
/* do something */
return Unit.INSTANCE;
})
결론적으로 Kotlin 에서 만드는 lib 은 Kotlin 과 Java 모두를 만족시키는 interface 로 만드는 것이 힘들 수 있다는 것.
그것에 대한 해결책으로 SAM param 과 lambda param 받는 overloading 을 해줘야 할 수 있다.
Closed by default
이 부분은 크게 공감가지 않아 정리하지 않음.
'프로그래밍 놀이터 > Kotlin, Coroutine' 카테고리의 다른 글
[Kotlin] Kotlin 의 숨겨진 비용 #2 (0) | 2018.01.17 |
---|---|
[Kotlin] Kotlin 의 숨겨진 비용 #1 (2) | 2018.01.16 |
[Kotlin] Kotlin 은 Compile time 이 느리다는데.. 사실일까? (0) | 2017.09.26 |
[Kotlin Tutorial] The Kotlin ecosystem (0) | 2017.09.22 |
[Kotlin Tutorial] Documenting Kotlin code (0) | 2017.09.20 |
댓글