Kotlin - Scope Function
Updated:
-
let
함수를 호출하는 객체를 이어지는 블록의 인자로 넘기고, 결과값을 반환.
-
표준 함수 정의 - T, R은 형식 매개변수로 어떤 자료형이라도 사용가능하다는 표시를 일반화한 문자
public inline fun <T, R> T.let(block: (T) -> R): R { ... return block(this) }
-
예시
fun main(){ val score:Int? = 32 fun checkScore(){ if(score != null) println("Score : $score") } fun checkScoreUsingLet(){ score?.let{println("Score : $it")} val str = score.let { it.toString() } println(str) } checkScore() // Score : 32 checkScoreUsingLet() // Score : 32 } //null 가능성 있는 객체에서 활용 obj?.let { // obj가 null이 아닐 경우 작업 수행 (Safe calls + let 사용) Toast.makeText(applicationContext, it, Toast.LENGTH_LONG).show() }
-
체이닝(메서드 혹은 함수를 연속적으로 호출하는 기법) 에서도 사용 가능하다. 가독성을 고려 할 때 너무 많은 let 사용은 권장되지 않음.
var a = 1 var b = 2 a = a.let { it + 2 }.let { val i = it + b i // 마지막 식 반환 } println(a) //5
-
-
also
함수를 호출하는 객체 T를 이어지는 block에 전달하고 객체 T 자체를 반환.
let
과 역할이 거의 동일해 보이지만 also는 결과와 상관없이 객체를 반환한다.-
표준 함수 정의
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
-
예시
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) // -> Person(name=Kildong, skills=Android) println("a: $a") // -> a: success val b = person.also { it.skills = "Java" "success" } println(person) // -> Person(name=Kildong, skills=Java) println(b) // -> Person(name=Kildong, skills=Java) }
-
-
apply
also
와 마찬가지로 호출하는 객체를 전달하고 반환한다.특정 객체를 생성하면서 함께 호출해야하는 초기화 코드가 있을 경우 사용 가능, 람다식이 확장함수로 처리가 가능하다.
-
표준 함수 정의
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") person.apply { this.skills = "Swift" } println(person) // -> Person(name=Kildong, skills=Swift) val returnObj = person.apply { name = "Sean" skills = "Java" } println(person) // -> Person(name=Sean, skills=Java) println(returnObj) // -> Person(name=Sean, skills=Java) }
-
-
run
인자가 없는 익명함수처럼 단독 사용하거나, 확장 함수 형태로 호출하는 형태 2가지로 사용가능하다.
독립적으로 사용시 block에 처리할 내용을 넣어주며 마지막 식이 반환됨
-
표준 함수 정의
public inline fun <R> run(block: () -> R): R = return block() public inline fun <T, R> T.run(block: T.() -> R): R = return block()
-
예시
fun main(){ //apply vs run data class Person(var name: String, var skills: String) var person = Person("Kildong", "Kotlin") val returnObj = person.apply { name = "Sean" skills = "Java" "success" // -> 사용되지 않음 } println(person) // Person(name=Sean, skills=Java) println(returnObj) // Person(name=Sean, skills=Java) val returnObj2 = person.run { name = "Dooly" skills = "C#" "success" } println(person) // Person(name=Dooly, skills=C#) println(returnObj2) // success } //safe call 사용 가능 obj?.run{ ... }
-
-
with
run
과 기능이 거의 동일하지만 receiver로 전달할 객체를 처리한다. 확장 함수 형태가 아니고 단독으로 사용되고 세이프콜은 지원하지 않기에 let과 함께 사용한다. 혹은 null 인 경우를 처리하려면 run을 확장 함수 형태로 사용한다.-
표준함수
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
-
예시
fun main{ data class User(val name: String, var skills: String, var email: String? = null) val user = User("kildong", "default") val result = with(user) { skills = "Kotlin" email = "kildong@exmaple.com" } println(user) //User(name=kildong, skills=Kotlin, email=kildong@exmaple.com) println(result) //kotlin.Unit } //null 경우 처리 -> let과 함께 사용하거나 run사용 supportActionBar?.let { with(it) { setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_clear_white) } } supportActionBar?.run { setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_clear_white) }
-