[컴][자바][안드로이드] anko



오늘은 anko 에서 view 를 확장할 때 쓰이는 방법을 통해 kotlin 을 조금 봐보자.

anko 에서 builder 에 쓰이는 view 를 추가할 때 아래와 같은 방법을 사용한다.
fun ViewManager.simpleDrawer(init: SimpleDrawer.() -> Unit = {}) =
        __dslAddView({ SimpleDrawer(it) }, init, this)

오늘은 이녀석을 좀 더 자세히 봐보도록 하자. kotlin 을 시작한지 얼마안돼서 그런지 아직 이녀석 code 가 익숙하지 않다. 개인적으로 kotlin 이 가독성이 별로라고 여겨지고 있지만, 볼 수록 요령은 생기는 듯 하다.


function literal

먼저 아래 문법을 조금 익혀보자. kotlin 에서 function literal 이라고 부르는 녀석이다.
val sum = {x: Int, y: Int -> x + y}
val sum: (Int, Int) -> Int = {x, y -> x + y}
위의 두개는 함수인데, 같은 의미를 갖는다. 단지 type 을 어디에 적어놓는지에 차이가 있을 뿐이다.
val sum = {x: Int, y: Int -> x + y}
val sum: (Int, Int) -> Int = {x, y -> x + y}

사실 kotlin 을 처음 접하면 아래 문법도 낯설다.
{x: Int, y: Int -> x + y}
위의 녀석을 일반적인 함수로 표현한다면 아래처럼 표현될 것이다.(javascript 문법을 가져왔다. int 는 그냥 다른 언어에서 ^^;;)
function(int x, int y){
  return x + y
}

1개의 parameter

근데 kotlin 은 좀 더 간단한 표현을 위해 parameter 가 1개일 때 경우에 좀 더 우아하게(?) 쓸 수 있는 법을 제공한다.
{x: Int  -> x + 1}
이 녀석은 아래처럼 된다.
{it: Int  -> it + 1}
그리고 이 녀석은 다시 아래 처럼 쓸 수 있다.
{it + 1}


{ SimpleDrawer(it) }
위에서 쓰인 위와 같은 녀석은 결국 아래의 모습인 것이다.
{ it -> SimpleDrawer(it) }


괄호 생략

그리고 한가지 더 kotlin 에서 만약 마지막 parameter 가 function type 이라면, 괄호를 그 이전의 parameter 에서 닫을 수 있다.
val result = lock(lock, { sharedResource.operation() }) 
위의 모습은 괄호를 생략해서 아래처럼 쓸 수 있다.
val result = lock(lock) { 
    sharedResource.operation() 
}) 



자, 이제 anko code 를 봐보자. 조금 수월할지도 모르겠다.

fun ViewManager.simpleDrawer(init: SimpleDrawer.() -> Unit = {}) =
        __dslAddView({ SimpleDrawer(it) }, init, this)

public fun <T : View> __dslAddView(view: (ctx: Int) -> T, init: T.() -> Unit, manager: ViewManager): T {
    return manager.addView<T> { ctx ->
        val v = view(ctx)
        v.init()
        v
    }
}

public inline fun <T: View> ViewManager.addView(factory: (ctx: Context) -> T): T {
    return when (this) {
        is ViewGroup -> {
            val view = factory(this.getContext())
            addView(view)
            view
        }
        is UiHelper -> {
            val view = factory(ctx)
            addView(view, null)
            view
        }
        else -> throw AnkoException("$this is the wrong parent")
    }
}



See Also




Reference

  1. JetBrains/anko · GitHub > Is it extensible?


댓글 없음:

댓글 쓰기