[Kotlin] Tip
Kotlin. Java 대비 장점이 무엇인가?
Java도 버전 올라가면서 """ string, when expression, utility stream API 등 코틀린을 쓰면서 느꼈던 장점들이 보완되고 있다.
그렇다면 코틀린을 써야 할 이유가 있는가?
- 코틀린과 Java의 가장 큰 차이는, 자바는 모든 타입이 Nullable이라는 명확한 한계를 가지고 있다는 점이다. Optional이 있지만 제한적이다. 컴파일 타임에 아예 널이 될 수 없음을 강제하는 코틀린의 컨셉과는 확실한 수준 차이가 있다.
- Coroutine이라는 더 나은 동시성 처리 방법을 지원한다. java도 많이 편해졌지만, 결국 Mono, Flux. reactive까지다.
- 마지막으로 Java가 많이 좋아졌다고는 하지만 아직도 default arg named param 같은 소소한 기능에서, 언어차원에서의 지원하지 않아 builder를 거쳐야 하는 등 지원이 미흡한 부분이 있다. 개발 하다 보면 소소하게 코틀린이 낫다고 생각되는 부분이 분명 존재한다.
- Named parameter를 지원한다. 단, 자바로 작성한 코드를 호출할 때는 사용할 수 없다.
- Default argument를 지원한다. 단, 자바에서 코틀린 코드를 호출할 때는 동작하지 않기 때문에 모든 params를 명시해주거나, ``kt @JvmOverloads`` 애노테이션으로 해결할 수 있다.
- ``kt val``은 ``kt init``에서도 초기화 할 수 있으니 꼭 선언하면서 동시에 초기화 할 필요는 없다. ``kt init``에 적기 전까지는 IDE에서 빨간 밑줄 처리하긴 한다.
- 하지만 ``kt var``은 private이거나 final인 경우에만 init block에서 초기화가 가능하다.(또는 lateinit 써주거나)
- final 이어야만 init에서 초기화 가능하다는 것은, init에서 호출하면 setter가 호출될텐데 하위 클래스에서 setter가 override되어 의도와 다르게 동작하는 경우를 방지하기 위한 것으로 보임.
- kotlin에서 final 키워드는 상속을 금지한다는 의미로, 자바의 final과 다른 의미다.
- 원래 Kotlin에서는 필드는 기본이 final이지만, Spring Bean annotation 붙여주는 경우 해당 클래스가 allopen 될 수 있음. (allopen plugin)
애너테이션
주생성자에 애너테이션 붙이는 경우, 애너테이션 타겟에 `` FIELD, PARAMETER``가 둘 다 존재하는 경우라면
필드에 붙이는건지 생성자 파라미터에 붙이는건지 애매할 수 있다.
(Byte code 변환 후 Java로 Decompile 해보면 알 수 있음)
필드에 붙이려면 @field: 명시해준다.
```kt
@field:Positive
```
숫자 타입은 가독성을 위해 언더바 를 넣을 수 있음
```kt
val krw = 2_000_000
```
""" 들여쓰기 제거
```kt
println("""
aaa
bbb""".trimIndent())
```
!in
데이터가 집단에 속하는지는 ``kt in``으로 검사. 부정은 ``kt !in``
```kt
fun isNotDigit(c: Char) = c !in '0'..'9'
isNotDigit('a')
```
loop , 반복
```kt
for (i in 0..10) // 0 1 2 3 4 5 6 7 8 9 10
for (i in 0 until 10) // 0 1 2 3 4 5 6 7 8 9 == python range(10)
for (i in 10 downTo 0 step 2) // 10 8 6 4 2 0
for (c in 'A'..'F') // ABCDEF
```
python의 ``py enumerate``같은 기능은 ``kt .withIndex()``다.
구조 분해 선언(destructuring declaration)이 가능하기 때문에 다음과 같이 쓸 수 있다.
```kt
val list = 'A'..'F'
for ((i, c) in list.withIndex()){
println("test $ $")
}
```
단순 for 말고 repeat() 도 괜찮음
```kt
repeat(times = repeatMax - 1) {
...
}
```
iterator가 아닌 타입을 iterable로 : asIterable()
List로 변환해서 이걸 써도 되기는 하는데, asIterable이라는 유틸리티가 있긴 하다.
* forEach도 있어서 이걸 써도 된다.
```kt
for (repo in repos!!.asIterable()) {
Log.d(DBG_TAG, repo.toString())
}
```
상수 : 최상위 프로퍼티
최상위 프로퍼티도 접근자 메소드가 생성되고, 이를 통해 접근하게 되기 때문에 상수처럼 쓰고 싶은 경우 자연스럽지 못하다. 이런 경우 ``kt const``를 붙이면 ``java public static final``로 지정된다.
```kt
const val COUNT = 5
```
inline 사용 예
그냥 코드에 매번 ``kt if``로 검사
-> ``kt if`` 검사를 메소드로 뺌(``kt isXXX()``)
-> 이를 ``kt inline``으로 만들어서, 매 코드마다 ``kt if``로 검사하는 것과 동일한 효과를 가져온다.
```kt
inline fun ifConThenRun(code: () -> Unit) {
if (SomeCondition) {
code()
}
}
>>> ifConThenRun { userCode() }
```
* 람다를 인자로 받을 때는 이런 식으로 적는다.
* ``kt Unit``말고 다른 타입을 지정해도 된다. 람다 자체는 뭘 리턴하든 별 상관이 없기 때문. 중요한건 함수 전체의 리턴값이다.
buildString : 문자열 만들기 제일 간단하게 처리하기
``kt StringBuilder()``를 만들고, ``kt .toString()``을 반환하는 것을 자동으로 처리해주는 ``kt buildString``이 있다.
```kt
for alphabet() = buildString {
for (letter in 'A'..'Z') {
append(letter)
}
}
```
'Java Stack > Kotlin' 카테고리의 다른 글
[Kotlin] enum / when / sealed (0) | 2017.12.01 |
---|---|
[Kotlin/Java] Inner Class / Nested Class (0) | 2017.12.01 |
[Regex] Kotlin (0) | 2017.12.01 |
[Kotlin] 확장 함수 / 확장 프로퍼티, 최상위 함수 / 최상위 프로퍼티 (0) | 2017.12.01 |
[Kotlin] Tip2 + 문자열 템플릿 (0) | 2017.11.30 |