본문 바로가기

Reading Record/이펙티브 코틀린

[이펙티브 코틀린] Item 38. 연산 또는 액션을 전달할 때는 인터페이스 대신 함수 타입을 사용하라

아이템 38

연산 또는 액션을 전달할 때는 인터페이스 대신 함수 타입을 사용하라

  • 코틀린은 연산을 전달할 때 SAM을 이용해 전달 가능하다.
interface  OnClick{
    fun click()
}

fun setOnClickListener(listener:OnClick){
    //..
}

fun main() {
    setOnClickListener(object :OnClick{
        override fun click() {
            //..
        }
    })
}
  • sam이 아닌 함수타입을 전달할 경우 더 많은 방법으로 파라미터 전달이 가능하다.
fun setOnClickListener(listener: ()->Unit){
//..
}

class ClickListener: ()->Unit{
    override fun invoke() {
        //
    }

}

fun main() {
    //람다 or 익명함수
    setOnClickListener{}
    setOnClickListener(fun (){}) 

    //레퍼런스 전달
    setOnClickListener(::println) 

    //선언된 함수 타입을 구현한 객체로 전달
    setOnClickListener(ClickListener())
}
  • typealias OnClick2 = () ->Unit
    • 위 키워드를 사용하면 타입 함수를 이름을 가진 타입처럼 사용할 수 있다.

SAM을 사용하는 경우

  • 자바에서 코틀린의 함수타입을 사용하려면 Unit을 명시적으로 리턴하는 함수가 필요하다.
class View(){
  var onDateClicked: ()->Unit? = null
  var onPageChanged: OnDateClicked? = null
}

interface OnDateClicked{
   fun onClick(date:Date)
}

//java
CalendarView c = new CalendarView();
c.setOnDateClicked(()->Unit.INSTANCE);
c.onPageChanged(()->{});

위 코드의 경우 sam을 사용하는 것이 더 합리적인 방법이다.