표준 함수란?
- Kotlin에서 보편적으로 사용되는 유틸리티 함수이며, 람다를 인자로 받아 동작한다.
- 이 포스팅에선 (apply, let, run with, also, takeIf) 6개의 사용 방법을 알아본다
- Kotlin 표준 함수는 내부적으로 확장 함수(extension function)이며, 확장 함수를 실행하는 주체를
수신자 또는 수신자 객체라고 한다.
- 따라서 확장 함수가 호출될 때 수신자 객체의 참조가 확장 함수로 전달된다.
apply
- apply 함수는 사용할 객체를 생성 시 생성할 객체를
apply 수신자 객체에 전달하고, 수신자 객체의 할 일이 종료되면 객체를 반환합니다.
- 특정 객체를 생성하면서, 객체를 초기화 할 코드가 있는 경우 사용됩니다.
- 아래 코드를 보면 apply 함수를 사용하면 하나의 블럭에서 객체의 초기화를 진행하여
가독성에 도움이 되는 걸 확인 할 수 있다.
- 또한 apply 람다 내부의 모든 호출은 수신자에 관련되어 호출되므로
이것을 연관 범위(relative scoping) 혹은 암시적 호출(implicitly called)이라고 한다.
fun main(args: Array<String>) {
//apply 함수를 사용하여 User객체를 생성한 예제
val user:User = User().apply {
name = "Choi"
age = 20
sex = 'M'
}
//apply 함수 없이 User객체를 생성한 예제
val user2:User = User()
user.name = "Choi"
user.age = 20
user.sex ='M'
}
let
- let 함수는 함수에 인자로 전달된 람다를 실행한 후 결과를 반환해 준다.
- let 함수는 어떤 종류의 수신자 객체에서도 호출 가능하다.
- it 키워드를 사용해서 let을 호출한 수신자 객체를 참조할 수 있다.
//List에 저장된 첫번째 요소의 제곱을 구하는 코드
fun main(args: Array<String>) {
val firstItemSquared:Int = listOf(1,2,3).first().let {
it * it
}
println(firstItemSquared)
}
- 만일 위에서 let 함수를 사용하지 않았다면 별도의 변수를 지정해줘야 한다.
fun main(args: Array<String>) {
val firstItem:Int = listOf(1,2,3).first()
val firstItemSquared = firstItem * firstItem
println(firstItemSquared)
}
- null 복합 연산자와 같이 사용하면 null 가능 타입에서 발생될수 있는 예외를 방지하며 기본값을 지정 할 수 있다.
fun main(args: Array<String>) {
var name: String? = null
name = name?.let {
"이름이 $it 님 이시군요"
} ?: "앗 현재 이름이 없으시군요."
println(name)
}
run
- run은 람다의 실행 결과를 반환한다.
- run은 수신 객체에서 호출한 run과 , 수신 객체 없이 호출된 run의 형태가 있습니다.
- run 어떤 값을 계산할 필요가 있거나, 여러개의 지역변수 사용범위를 제현하기 위해 사용합니다.
fun main(args: Array<String>) {
val isHaveName: Boolean = run { //이름이 있는지 판단하는 용도로 User 객체가 필요하면
val user: User = User() // run으로 범위를 지정해 사용 할 수 있다.
user.name != ""
}
User().run{ //수신자 객체를 대상으로 run함수를 사용하면
println(name) //수신자 객체의 요소를 사용할 수 있다.
}
}
with
- with은 수신자 객체를 첫 번째 매개변수 인자로 받는다. (아래 예제 참조)
fun main(args: Array<String>) {
val isMsgToLong = with("This message is .... long.. .... . . . . "){
length >= 20
}
println(isMsgToLong)
}
also
- also는 let처럼 자신을 호출한 수신자 객체를 람다의 인자로 전달한다.
- also는 let과는 달리 람다의 결과가 아닌 수신자 객체를 반환한다.
- 아래 코드와 같이 서로 다른 처리를 also를 사용해 연쇄 호출할 수 있다.
fun main(args: Array<String>) {
val user:User = User().also{
it.name = "Choi"
}.also {
it.age = 28
}.also {
println("${it.name} ${it.age}")
}
}
takeIf
- 람다에 제공된 조건식을 실행한 후 그 결과에 따라 true 또는 false를 반환한다.
조건식의 결과가 true이면 수신자 객체가 반환되며 false이면 null이 반환된다.
fun main(args: Array<String>) {
val user:User? = User().takeIf { it.name == "Choi" }
println(user?.name)
println(user?.age)
}
takeUnless
- takeIf를 보완하는 함수이며 구조는 takeIf와 동일하지만 조건식이 false일 때
수신자 객체를 반환한다는 점이 다르다.
표준 함수 정리표
함수 | 수신 객체를 람다의 인자로 전달하는가? | 연관 범위를 제공하는가? | 반환 |
let | Yes | No | 람다의 결과 |
apply | No | Yes | 수신자 객체 |
run | No | Yes | 람다의 결과 |
with | No | Yes | 람다의 결과 |
also | Yes | No | 수신자 객체 |
takeIf | Yes | No | 수신자 객체 or null |
takeUnless | Yes | No | 수신자 객체 or null |
[Kotlin] Object & Companion Object (0) | 2021.09.21 |
---|---|
[Kotlin] Data Class (데이터 클래스) (0) | 2021.09.21 |
[Kotlin] 문자열 (0) | 2020.12.05 |
[Kotlin] 익명 함수와 함수 타입 (1) | 2020.12.05 |
[Kotlin] 함수(Function) (0) | 2020.12.04 |