1. filter 의 결과물을 let 으로 1개 또는 여러개의 작업수행
val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let {
println(it)
// and more function calls if needed
}
위의 예시에서 만약 let{ } 블럭 안에 하나의 function 만을 포함하며 매개변수가 1개의 it일 경우
.let(::println)
으로 대체가능하다.
2. Not Null 체크
val str: String? = "Hello"
//processNonNullString(str) // compilation error: str can be null
val length = str?.let {
println("let() called on $it")
processNonNullString(it) // OK: 'it' is not null inside '?.let { }'
it.length
}
위의 예시처럼 ?.let 을 통해 해당 변수 또는 결과물의 null 이 아닌지 여부를 체크한다. null이 아닐 경우에 {} 블록이 동작한다.
3. 결과 값 대입
val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
println("The first item of the list is '$firstItem'")
if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.toUpperCase()
println("First item after modifications: '$modifiedFirstItem'")
first() 의 결과물로 .let 을 진행하면서 블록 {} 내에 firstItem 이 결과물이다.
modifiedFirstItem 에 지정되어질 값으로 firstItem 값이 5 이상일 경우 firstItem 값이 그렇지 않으면 앞뒤로 "!" 가 붙으며 모두 대문자로 변경된 값이 지정된다.
이처럼 let 은 단순히 null 체크 뿐 아니라 하나의 변수 또는 결과값을 하나 또는 여러개의 함수에서 쓰게되어 {} 블록으로 묶어 줌으로써 좀 더 간결하게 코드를 작성할 수 있다.
4. if NotNull else Null
val tempMap = mutableMapOf<String, String>()
private fun calculatedFee(): Int? {
//...
return 1000
}
fun A() {
calculatedFee()?.let {
//null 이 아닐경우
println("The fee is not null")
tempMap.put("hi","hi")
//(중요) 위의 tempMap 리턴이 null 이 아니면 하단의 ?: run {} 블록이 동작해버리게 된다.
//println("ok!")
//위의 println 주석을 풀면 아래의 null 일 경우의 블록은 정상동작한다.
} ?: run {
println("The fee is null")
//null 일 경우
}
}
기본적으로 ?.let{...} :? run{} 는 값이 null 일 경우까지 처리해주는 코드이다.
*** 주의
위의 코드에서 ?.let{} 안의 블록에서 행해지는 코드의 내부 결과가 Map.put() 객체를 리턴하는 케이스의 경우, ?: run{} 의 스코프까지 동작되어 ?.let{} 블럭과 ?:run{} 블럭 모두 작동되어 버린다. Map.put() 리턴 객체의 경우에만 이런 케이스가 발생하는 것 같다. List.add() 는 정상적으로 NotNull 이 동작한다. 다른 케이스도 좀 더 테스트 해봐야겠다.
위의 코드를 돌리면
으로 결과가 나타난다.
println("ok!") 만 주석해제하면 정상동작 한다.
(이것 때문에 한참 삽질...)
혹시 정확한 이유를 아신다면 댓글좀 남겨주세요 ㅜ
(출처)
kotlinlang.org/docs/scope-functions.html#let