엄범


코틀린이 좋은 이유는, 언어 설계자들의 생각과 의도가 명확하게 나타나기 때문인 것 같다. 언어에서 제안하는 대로, 지원하는 문법 대로 따라가면 깔끔한 형태로 코드가 작성되도록 만들어 두었다는 생각이 듦.

한 예가 data class의 toString 메서드는 주 생성자에 있는 프로퍼티만 가져와서 띄워 준다는 것?


  • Named parameter를 지원한다. 단, 자바로 작성한 코드를 호출할 때는 사용할 수 없다.
  • Default argument를 지원한다. 단, 자바에서 코틀린 코드를 호출할 때는 동작하지 않기 때문에 모든 params를 명시해주거나, ``kt @JvmOverloads`` 애노테이션으로 해결할 수 있다.
  • ``kt val``은 ``kt init``에서도 초기화 할 수 있으니 꼭 선언하면서 동시에 초기화 할 필요는 없다. ``kt init``에 적기 전까지는 IDE에서 빨간 밑줄 처리하긴 한다.


LoggerFactory.getLogger Best Practice

```kt

inline fun <reified T> T.log() = LoggerFactory.getLogger(T::class.java)

```

https://www.baeldung.com/kotlin-logging


""" 들여쓰기 제거

```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 ${i} ${c}")
}
```

배열에 연산을 적용한 결과가 필요하거나, 그냥 간결하게 사용하는 일반적인 경우에는 ``kt filter()/map()`` 같은 고차 함수를.
결과가 필요 없고 고차 함수를 사용하면 조금 난잡해 지는 경우 단순 ``kt for``
``kt forEach``는 웬만하면 지양.

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)

    }

}

```