firebase 를 사용하기 위해서 구글 샘플 분석하다가 람다의 늪에 빠져서 허우적 대고 있었다

람다식이니 고차함수니 하는 용어들을 통해 수년동안 등한시했던 프로그래밍 패러다임의 변화를 어렴풋이 알게 되었는데

전산분야에서는 모바일 디바이스 때문에 각 개발언어 플랫폼들의 실행 성능에 대해 다시 한번 재검토 된 듯 보인다

불과 며칠사이에 이를 익힐 수 있게 된 것은 너무나 고마운 구글과 네이버 덕분이었다

그렇게 익힌 지식을 기반으로 다음의 코드를 분석하고 기록한다

 

 

findViewById<View>(R.id.select_image_button)
  .setOnClickListener { view: View ->
    // Menu for selecting either: a) take new photo b) select from existing
    val popup =
      PopupMenu(this@StillImageActivity, view)
    popup.setOnMenuItemClickListener { menuItem: MenuItem ->
      val itemId =
        menuItem.itemId
      if (itemId == R.id.select_images_from_local) {
        startChooseImageIntentForResult()
        return@setOnMenuItemClickListener true
      } else if (itemId == R.id.take_photo_using_camera) {
        startCameraIntentForResult()
        return@setOnMenuItemClickListener true
      }
      false
    }
    val inflater = popup.menuInflater
    inflater.inflate(R.menu.camera_button_menu, popup.menu)
    popup.show()
  }

 

위 코드블럭에서 너무나 생소했던 부분이 두번째 라인의 setOnClickListener 의 정의였다

setOnClickListener { view:View -> 에는 kotlin 과 lamda 의 활용이 있었다

 

setOnClickListener 함수를 java에서 구현한다면 코드가 다음과 같다

public void setOnClickListener(OnClickListener l) {

   ...

}

 

kotlin 으로 작성한다면 다음과 같다

fun setOnClickListener(l: (View) -> Unit)

 

위와 같은 방식으로 익명 클래스를 만들어야 하는 경우엔 다음과 같이 정의할 수 있다

view.setOnClickListener(object : View.OnClickListener {

    override fun onClick(v: View?) {

        toast("Hello")

    }

})

 

위 코드를 kotlin 편집기에서 작성하면 경고를 표시하면서 lamda 방식을 사용할 것을 권장 받게 된다

그래서 lamda로 변환하게 되면

view.setOnClickListener({ v -> toast("Hello") })

 

위와 같은 코드에서 처럼 마지막 매개변수가 함수라면 중괄호 블럭을 소괄호 밖으로 꺼낼 수 있다

view.setOnClickListener() { v -> toast("Hello") }

 

또한 setOnClickListener 정의 내에 수행하는 함수가 하나만 있다면 괄호를 삭제할 수 있다 (참고링크)

view.setOnClickListener { v -> toast("Hello") }

 

여기까지의 내용으로 처음의 코드 블럭의 내용이 비로서 이해가 갔다

그리고 더 나아가 다음과 같은 내용도 알게 되었다

 

lamda의 매개변수를 사용하지 않는 경우 함수 왼쪽까지 제거가 가능하다

view.setOnClickListener { toast("Hello") }

 

또한 매개변수만 받는 함수에서는 왼쪽을 정의하는 대신 예약어 it 을 사용하여 일부 문자를 절약 할 수 있다

view.setOnClickListener { v -> doSomething(v) }

예를 들어 위와 같이 뷰를 사용하여 다른 메서드에 전달한 경우를 절약한다면 다음과 같다

view.setOnClickListener { doSomething(it) }

 

 

위와 같은 내용으로 첫 문단의 코드 블락을 마지막으로 정리하자면

setOnClickListener 정의에서 처음 나타나는 매개변수 view는 단일 익명함수의 단 하나의 매개변수로써

view:View -> 코드 라인 이후에 PopupMenu의 생성자에서 한번 더 참조된다

그리고 popup메뉴 객체가 정의되면서 setOnMenuItemClickListener 함수도 동일하게 함수형 익명 객체로 정의하고 있다

이후 popup메뉴 객체는 사용자의 아이템 선택에 따라서 동적으로 생성된다