람다 표현식 : https://kotlinlang.org/docs/lambdas.html
코틀린에서 함수는 first-class 이다. 이 의미는 함수도 객체처럼 변수에 저장도하고, 인자로 넘기고, 리턴값으로 돌려줄 수도 있다는 얘기. 이와같이 다루기위해 함수 타입의 정의가 필요한데 다음과 같이 한다.
(Int, String) -> String // Int와 String타입의 두 개의 인자를 받고 String을 리턴하는 함수
() -> Unit // 인자가 없고 리턴값도 없는 함수
람다 표현식(Lambda expression)은 표현식이면서 하나의 함수로 syntax예제는 다음과 같다.
val sum: (Int, Int) -> Int = { x:Int, y: Int -> x + y } // 오른쪽 괄호 부분이 lambda expression
람다 표현식은 함수와 똑같이 중괄호로 묶인다. 파라미터를 나열하는 것으로 시작하여 화살표 ‘->’ 를 쓰고 표현식 바디부분을 기술한다. 리턴이 따로 표시가 없지만, 표현식인 만큼, 람다 표현식은 여러줄로 사용할 수도 있으며, 마지막 표현식의 값이 리턴값이 된다. 위 예에선 x+y값이므로 리턴값이 Int이다.
파라미터가 없다면, 파라미터와 ‘->’ 를 쓰지 않아도 된다. 파라미터가 하나인 경우에도 생략 가능하며, 이 때는 바디부분에서 “it”으로 사용할 수 있다. 예제는 다음과 같다.
ints.filter { it > 0 } // (it: Int) -> Boolean 타입
파라미터가 사용되지 않는 경우, 언더스코어 ‘_’로 자리를 채워놓을 수 있다.
map.forEach { (_, value) -> println("$value!") }

마지막 인자가 함수인 경우, 괄호 밖에 람다 표현식으로 사용하기. : https://kotlinlang.org/docs/lambdas.html#passing-trailing-lambdas
코틀린에서 함수의 마지막 인자가 함수 타입인 경우, 인자의 괄호 밖에 마치 함수 바디처럼 람다 표현식 사용이 가능하다. 람다 표현식 형태의 함수가 내용이 길어질 수 있으므로 매우 유효한 형태이다.
// fold 함수 선언을 보면 다음과 같다.
inline fun <T, R> Array<out T>.fold(
initial: R,
operation: (acc: R, T) -> R
): R
// fold 함수의 사용
val product = items.fold(1) { acc, e -> acc * e }
위 예에서 확장 함수 fold()의 두번째 인자가 함수 타입이고, 실제 사용에선 람다 표현식으로 넘겨주고 있다.

A.(B) -> C : https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver
보다보면 A.(B) -> C 와 같은 형태의 표현을 보게 되는데, 리시버 오브젝트를 가지는 함수 타입이다. 리시버 오브젝트에 직접 접근한다는 부분에서 확장함수와 유사하다.
val sum: Int.(Int) -> Int = { other -> plus(other) }
anonymous function을 이용하면, 다음과 같이 사용도 가능하다.
val sum = fun Int.(other: Int): Int = this + other
람다 표현식은 함수와 동일하므로, 위의 타입에 대입하여 사용가능하다. 예를 보자.
class HTML {
fun body() { ... }
}
fun html(init: HTML.() -> Unit): HTML {
val html = HTML() // create the receiver object
html.init() // pass the receiver object to the lambda
return html
}
html { // lambda with receiver begins here
body() // calling a method on the receiver object
}
fun html은 인자로 리시버 오브젝트 HTML을 갖는 함수 타입을 받는다. 마지막 부분을 보면, body()를 실행하는 람다 표현식을 인자로 넘기고 있다. fun html() 내부에서는 리시버 오브젝트에 이 람다 표현식을 붙여서 리시버 오브젝트를 전달하고 있다.

Null Safty : https://kotlinlang.org/docs/null-safety.html
코틀린은 null에 엄격한 언어로 변수에서 null이 가능한지 미리 정해놓고 시작한다. 또한, 이런 null체크를 도와주는 것들이 있다. 이런 부분들은 NPE( Null Pointer Exception)을 예방하는데 큰 도움이 된다.
일반적으로 변수를 선언하면, 이 변수들은 Null을 갖을 수 없다.
// Assigns a non-null string to a variable
var a: String = "abc"
// Returns the length of a non-nullable variable
val l = a.length
print(l) // 3
// Attempts to re-assign null to the non-nullable variable
a = null
print(a)
// Null can not be a value of a non-null type String
위 예에서 a 는 null값을 절대 갖지 않으므로, a.length를 사용하는데 아무런 위험 부담이 없다. 하지만, 아래쪽에 null을 대입하려 한다면 에러가 날 것이다.
null이 가능한 변수는 ‘?’를 더해준다.
// Assigns a nullable string to a variable
var b: String? = "abc"
// Successfully re-assigns null to the nullable variable
b = null
print(b)
// null
문제는 이제 b의 멤버를 참조하거나 할 때, NPE의 위험이 생기게 된다. 다른 언어에서 가장 쉽게 볼 수 있는 방법은 if문을 이용한 null 체크일 것이다. 여기선 패스. 코틀린은 더 다양한 해결책을 준다. 먼저 safe call operator 인 ‘?.’ 을 제공한다. 이는 멤버를 참조하기 전에 객체가 null이면 참조를 하지않고 바로 null을 돌려준다.
// Assigns a nullable string to a variable
val a: String? = "Kotlin"
// Assigns null to a nullable variable
val b: String? = null
// Checks for nullability and returns length or null
println(a?.length)
// 6
println(b?.length)
// null
다음으로 Elvis operator ‘?:’ 가 있다. safe operator는 객체가 null이면 null을 돌려줬지만, 이건 null이 아닌 다른값을 돌려준다.
// Assigns null to a nullable variable
val b: String? = null
// Checks for nullability. If not null, returns length. If null, returns a non-null value
val l = b?.length ?: 0
println(l)
// 0
위와 같이 사용하면, b?.length가 null이 아니면 값을 돌려주고 null인 경우 오른쪽의 값인 0를 돌려준다.
세번째로 not-null assertion operator가 있다. 이는 null이 가능한 변수에 대해 개발자가 컴파일러에게 여기서는 null이 될 수 없음을 알려주는 연산자이다. 다만, 잘못사용하면 NPE 의 가능성이 있으므로 주의하자.
// Assigns a nullable string to a variable
val b: String? = "Kotlin"
// Treats b as non-null and accesses its length
val l = b!!.length
println(l)
// 6