이번 글은 "이런 식으로 만들 수도 있구나..!" 라는 정도로만 읽어주시면 감사하겠습니다.
코틀린에는 invoke
관례라는 것이 있습니다.
함수의 이름을 invoke
로 짓고 operator
키워드를 통해 연산자 오버로딩을 하게 되면,
관례에 따라 그에 맞는 기능을 하도록 정의됩니다.
특히 invoke
관례는 잘못 사용하면 알 수 없는 코드를 만들 수 있습니다.
자바에서는 연산자 오버로딩 기능을 지원하지 않습니다.
하지만 코틀린에서는 개발상 편의를 위해서 관례
를 이용하여 이를 구현합니다.
코틀린에는 plus
, minus
, get
, getValue
, invoke
등
수많은 연산자 오버로딩용 관례가 있습니다.
이 중 가장 괴랄한? invoke
연산자에 대해서 알아보도록 하겠습니다.
invoke
메소드의 관례는
이 메소드를 호출할 때는 메소드의 이름을 명시하지 않아도 된다는 것입니다.
class AnyClass {
operator fun invoke() = println("any class")
}
이렇게 invoke
연산자를 정의하게 되면 다음과 같이 사용할 수 있습니다.
val anyClass = AnyClass()
anyClass()
anyClass()
는 사실 anyClass.invoke()
로 컴파일 됩니다.
이는 this
를 리턴하는 방식을 통해 속임수를 사용한 것입니다.
실제 Hello
클래스는 다음과 같습니다.
class Hello {
operator fun invoke(): Hello {
println("hello")
return this
}
}
따라서 Hello()()()()()
는 괄호의 갯수 - 1만큼 hello
를 출력하게 됩니다.
또한 실제로 Hello()()()()()
는 다음과 같이 컴파일 됩니다.
Hello().invoke().invoke().invoke().invoke()
Hello()()()()()
는 invoke
관례를 이용한 꼼수입니다.