Kotlin: Function with receivers
2025. 10. 2. 13:56ㆍProgramming/JAVA, C++, Go, Rust
- 목차
반응형
리시버를 지닌 함수 리터럴은 다음과 같은 형태입니다.
A.(B) -> C
예를들어 다음과 같이 정의될 수 있습니다.
val sum: Int.(Int) -> Int = { other -> plus(other) }
이 경우 함수 리터럴의 바디 안에서 전달된 리시버 객체는 this가 되어 this 없이 그 멤버들에 접근이 가능합니다.
위 예에서도 Int의 plus에 접근하고 있습니다.
리시버가 없는 경우
Int의 확장함수 wrapper는 람다함수를 func로 받고 func에 this 즉, Int객체를 넘겨서 호출합니다.
람다 함수 내에서는 매개변수 it으로 hashCode()에 접근 합니다.
fun Int.wrapper(func: (num: Int) -> Unit) = func(this)
fun main(args: Array<String>) {
1000.wrapper {
print(it.hashCode())
}
}
리시버가 있는 경우
func는 Int 타입의 리시버를 갖는 함수 타입 입니다.
현재의 리시버는 코드가 실행되는 문맥(스코프)에서 this 객체 입니다.
wrapper는 Int의 확장함수이며, 1000.wrapper의 경우 this는 1000 입니다.
fun Int.wrapper(func: Int.() -> Unit) = func()
fun main(args: Array<String>) {
1000.wrapper {
print(hashCode())
}
}
Scope function
리시버 함수 타입의 사용처
apply, run, with와 같은 코틀린 표준함수 scope funcgtion들은 다음과 같이 구현되어 있습니다.
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 }
그래서 다음과 같이 사용할 수 있습니다.
apply의 경우 함수 타입에 리시버가 정의되어 있기에 this를 생략하고 Person 타입의 속성에 접근 할 수 있습니다.
fun main() {
data class Person(var name: String, var skills: String)
var person = Person("a", "Kotlin")
person.also { it.skills = "Java" }
person.apply { skills = "Swift" }
}
Android ex.
fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit) {
setSupportActionBar(findViewById(toolbarId))
supportActionBar?.run {
action()
}
}
....
setupActionBar(R.id.toolbar) {
setHomeAsUpIndicator(R.drawable.ic_menu) <- setHomeAsUpIndicator은 ActionBar의 member
setDisplayHomeAsUpEnabled(true)
}
...
반응형
'Programming > JAVA, C++, Go, Rust' 카테고리의 다른 글
Kotlin generics (0) | 2025.10.02 |
---|---|
backtrace 정보 출력 (0) | 2025.03.31 |
go get 오류 발생 시 대처 (0) | 2024.05.09 |
go profiler pprof 사용법 (0) | 2024.02.06 |
Study stuff for Golang (0) | 2023.07.24 |