함수를 호출하는 객체 T를 이어지는 block에 전달하고 객체 T 자체를 반환
// 표준 함수의 정의 let과 비교
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
also는 블록 안의 코드 수행 결과와 상관없이 T인 바로 객체 this를 반환
var m = 1
m = m.also { it + 3 }
println(m) // 원본 값인 1
사용 예
fun main() {
data class Person(var name: String, var skills: String)
var person = Person("Kildong", "Kotlin")
val a = person.let {
it.skills = "Android"
"success" // 마지막 문장을 결과로 반환
}
println(person)
println("a: $a") // String
val b = person.also {
it.skills = "Java"
"success" // 마지막 문장은 사용되지 않음
}
println(person)
println("b: $b") // Person의 객체 b
}
특정 단위의 동작 분리
디렉터리 생성 활용
// 기존의 디렉터리 생성 함수
fun makeDir(path: String): File {
val result = File(path)
result.mkdirs()
return result
}
// let과 also를 통한 개선된 함수
fun makeDir(path: String) = path.let{ File(it) }.also{ it.mkdirs() }
also() 함수와 마찬가지로 호출하는 객체 T를 이어지는 block으로 전달하고 객체 자체인 this를 반환
public inline fun <T, R> T.let(block: (T) -> R: R = block(this)
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
사용 예
fun main() {
data class Person(var name: String, var skills: String)
var person = Person("Kildong", "Kotlin")
// 여기서 this는 person 객체를 가리킴
person.apply { this.skills = "Swift" }
println(person)
val returnObj = person.apply {
name = "Sean" // this는 생략할 수 있음
skills = "Java" // this 없이 객체의 멤버에 여러 번 접근
}
println(person)
println(returnObj)
}
// Person(name=Kildong, skills=Swift)
// Person(name=Sean, skills=Java)
// Person(name=Sean, skills=Java)
레이아웃을 초기화할 때 apply() 사용