-
코드를 보다보니 이런 녀석을 보았다.
inline fun TextView.addTextChangedListener( crossinline beforeTextChanged: ( text: CharSequence?, start: Int, count: Int, after: Int ) -> Unit = { _, _, _, _ -> }, crossinline onTextChanged: ( text: CharSequence?, start: Int, count: Int, after: Int ) -> Unit = { _, _, _, _ -> }, crossinline afterTextChanged: (text: Editable?) -> Unit = {} ): TextWatcher { val textWatcher = object : TextWatcher { override fun afterTextChanged(s: Editable?) { afterTextChanged.invoke(s) } override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { beforeTextChanged.invoke(text, start, count, after) } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { onTextChanged.invoke(text, start, before, count) } } addTextChangedListener(textWatcher) return textWatcher }
자동완성으로는 이렇게만 나온다.
crossinline 이라는게 나오면서 정확히 어떻게 써야할지를 모르겠어서 공부해본다.
-
crossinline 은 lambda 가 nonlocal return 을 허용하지 않아야 한다는 것을 이야기한다.
이 녀석은 inline 되는 higher order function 에서 lambda 를 소비하는 것이 아니라 다른 곳으로 전달할 때 마킹을 해준다.
inline fun foo(crossinline f: () -> Unit){ boo{ println(“A”); f() } } fun boo(f: () -> Unit){ ... }
예제를 보면 f lambda 는 바로 소비되지 않고, boo 로 한번 더 전달이 된다.
전달이 되지 않는다면 inline 함수이기 때문에 non-local return 이 허용되지만, 한번 더 전달되므로 non-local return 을 할 수 없게 되고, 이것을 명시적으로 알리기 위해(함수 사용자 & compiler) crossinline 으로 마킹해준다.
-
다시 돌아가서 inline fun TextView.addTextChangedListener 이 녀석을 보면, 복잡하게 생겼지만 사실 간단한 녀석이었다.
beforeTextChanged, onTextChanged, afterTextChanged 3개의 lambda 를 param 으로 받으며 기본값으로 모두 아무것도 하지 않는 lambda 가 assign 이 되어 있다.
그리고 crossinline 이 마킹된 이유는 이것이 안쪽 코드의 실제 TextWatcher 에 전달되어 실행되기 때문이다.
-
사실 이 내용은 이전에 책에서 보고 정리했던 내용인데 잘 사용하지 않다보니 까먹게 된다.
정말 부단히 공부해야 하나보다 ㅎㅎ
-
끝!
'프로그래밍 놀이터 > Kotlin, Coroutine' 카테고리의 다른 글
[Kotlin] Coroutine 에 대한 이해 : 기본 용어 및 사용 (0) | 2020.08.07 |
---|---|
[Koin] Koin 에 대해 알아보자 (tutorial) (0) | 2020.08.06 |
[coroutine] Shared mutable state and concurrency (0) | 2020.03.13 |
[coroutine] Channels (5) | 2020.03.12 |
[coroutine] Asyncronous Flow (0) | 2020.03.11 |
댓글