2021. 9. 3. 14:23ㆍ바삭바삭 IT/코틀린
코틀린에서 아주 자주 볼 수 있는 범위지정함수 5가지를 정리합니다.
범위 지정 함수는 코틀린에서 표준 라이브러리를 통해 제공하고 있습니다.
- let()
- apply()
- with()
- run()
- also()
let()
let()은 이 함수를 호출한 객체를 이어지는 함수 블록의 인자로 전달합니다.
//1. 이 함수를 호출한 객체를 block의 인자로 전달하고 block의 결과를 반환
fun <T,R> T.let(block: (T) -> R): R
let은 불필요한 변수 선언을 방지할 수 있습니다.
//let 사용 전
val file = File(path)
if(!file.exists()){
throw FileNotFoundException(file.toString())
}
val metadata = loadModuleMetadata(file)
//let 사용 후
File(path).let {
if (!it.exists()) {
throw FileNotFoundException(it.toString())
}
val metadata = loadModuleMetadata(it)
}
또, let()은 간단하게 null을 체크하고 싶을 때 유용합니다.
//message가 null이 아닌 경우에만 let 함수 호출
message?.let{
showToast(message)
}
apply()
apply()는 이 함수를 호출한 객체를 이어지는 함수 블록의 리시버로 전달합니다.
//1. 이 함수를 호출한 객체를 block의 리비서로 전달하고 함수를 호출한 객체를 반환
fun <T> T.apply(block: T.() -> Unit): T
객체의 속성을 수정할때 매번 일일이 객체 이름을 명시하지 않아도 되어 코드를 간략히 줄일 수 있습니다.
//apply 적용 전
private val cal = Calendar.getInstance()
cal.set(YEAR, 1998)
cal.set(MONTH, SEPTEMBER)
cal.set(DAY_OF_MONTH, 4)
//apply 적용 후
private val cal = Calendar.getInstance().apply {
set(YEAR, 1998)
set(MONTH, SEPTEMBER)
set(DAY_OF_MONTH, 4)
}
with()
with()는 인자로 받은 객체를 이어지는 함수 블록의 리시버로 전달합니다.
//1. 인자 reciever를 이어지는 함수 block의 리시버로 전달, block의 결과를 반환
fun <T,R> with(receiver: T, block: () -> R): R
null이 아닌지 확인된 객체에 이 함수를 사용하는 것이 좋습니다.
with(viewModel) {
if (isFiltered()) {
clearGrowZoneNumber()
} else {
setGrowZoneNumber(9)
}
}
run()
run()은 아래 선언된 두가지 형태로 사용할 수 있습니다. 2번은 얼핏 apply와 비슷해 보이는데요. 차이점은 apply는 호출한 '주체'인 객체를 반환하는 반면, run은 block의 '결과'를 반환합니다.
//1. 함수형 인자 block을 호출하고 결과를 반환
fun <R> run(block: () -> R): R
//2. 이 함수를 호출한 객체를 block의 리비서로 전달하고 결과를 반환
fun <T, R> T.run(block: T.() -> R): R
1번처럼 익명함수처럼 사용할 경우, 복잡한 계산을 위해 임시 변수가 필요할때 유용합니다.
val padding = run {
val defaultPadding = 10
val extraPadding = 5
defaultPadding + extraPadding
}
2번의 run은 안전한 호출을 사용할 수 있어서 null값일 수 있는 객체의 속성이나 함수에 연속적으로 접근할 때 유용합니다.
lastInitialView?.run {
setText(player.lastInitial)
requestFocus()
setSelection(length())
}
also()
also()는 이 함수를 호출한 객체를 block의 인자로 전달하고, 함수를 호출한 객체를 반환한다.
fun T.also(block: (T) -> Unit): T
also()는 주로 객체의 속성을 바꾸지 않고 사용할 때 유용하다.
val extras = Bundle().also {
val position = preferences.getLong(KEY, 0L)
it.putLong(POSITION, position)
}
위 내용을 정리하면 아래와 같습니다.
범위 지정 함수 | input | return | 확장 함수인가? | 사용목적 |
let() | Parameter (it) | 람다함수 result | Y | null이 아닌 객체에 람다를 실행하고 싶을때 |
apply() | Reciever (this) | apply를 호출한 객체 자신 | Y | 객체의 여러 속성들을 설정할때 |
with() | Reciever (this) | 람다함수 result | N | 객체에 대해 그룹화 함수를 호출하고 싶을때 |
run() - 1 | None | 람다함수 result | N | 정규식 필요한 명령을 실행하고 싶을때 |
run() - 2 | Reciever (this) | 람다함수 result | Y | 객체의 여러 속성들을 설정하고 결과를 반환하고 싶을 때 |
also() | Parameter (it) | also를 호출한 객체 자신 | Y | 추가적인 영향을 주고싶을때 |
'바삭바삭 IT > 코틀린' 카테고리의 다른 글
[코틀린] var과 val의 차이 (0) | 2021.09.19 |
---|---|
[코틀린] 함수 호출시, 인자에 함수 대입하기 (0) | 2020.12.09 |