안드로이드

[안드로이드] Kotlin 범위 지정 함수(let, with, run, apply, also)

이손안나 2022. 3. 27. 19:18

코틀린 표준 라이브러리는 확장 함수들을 제공한다.

💡확장함수를 정의하는 방법은 일반 함수를 정의하는 방법에서 fun 키워드와 함수 이름사이에 확장할 클래스의 이름과 마침표를 붙여준다.

fun String.lastChar(): Char = this[this.lenth - 1] #확장함수의 정의
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    return receiver.block()
}

inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

- let() : 함수를 호출하는 객체를 이어지는 블록의 인자로 넘기고 블록의 결과값을 반환한다.

bob.let{
	println(it)
    it.move("korea")
    it.increament()
}

let은 주로 null이 아닌 값에 대해서 코드를 실행해야 하는 경우 사용. (null이면 실행되지 않음)

또한, let은 null을 체크하고 싶을 때 유용

message?.let{ showToast(message) } // message가 null이 아닌 경우에만 호출

 

- with() : 수신 객체이며 결과값이 필요 없을 때만 사용. (return 이 없음)

null이 아닌지 확인된 객체에 사용하는 것이 좋음.

with(viewModel){
	if(isFiltered() {
    	clear()
    } else {
    	set()
    }
}

 

- run() 

apply는 호출한 주체인 객체를 반환하는 반면, run은 block의 결과를 반환

 

1. 복잡한 계산을 위해 임시 변수가 필요할 때 유용

val padding = run{
	val defaultPadding =10
    val extraPadding = 5
    
    defaultPadding + extraPadding
}

2. run은 안전한 호출을 사용할 수 있어서 null값일 수 있는 객체의 속성이나 함수에 연속적으로 접근할 때 

textView?.run{
	setText(player.last)
    requestFocus()
}

- also() : 람다 내부에서 it으로 객체를 사용하고 객체를 반환. 수신 객체 람다가 전달된 수신 객체를 전혀 사용하지 않거나 수신 객체의 속성을 변경하지 않고 사용하는 경우.

* 블록함수가 다른 값을 반환 해야하는 경우에는 사용할 수 없다.

class Book(author: Person) {
	val author = author.also {
    	requireNotNull(it.age)
        print(it,.name)
    }
}

 

-apply() : 수신 객체를 이어지는 함수 블록의 리시버로 전달한다. 수신 객체 람다 내부에서 수신객체의 함수를 사용하지 않고 수신 객체 자신을 다시 반환하려는 경우에 사용. ex) 객체의 초기화

val peter = Person().apply{
	name = "Peter",
	age=18
}

 

 

🙌Examples

val r:R = with(T()) { this.foo(); this.toR() }
val r: R = T().run {this.foo();,this.toR() }
val r: R = T().let {it.foo();, it.toR() }
val t: T = T().apply { this.foo() }
val t: T = T().also {it.foo()}