Передача и использование функции в качестве аргумента конструктора в Котлине

Как создать класс, который принимает функцию в качестве аргумента конструктора. Затем используйте эту функцию в какой-то более поздней точке класса.

У вас может быть свойство с типом функции, как и с любым другим типом:

class A(val f: () -> Unit) { fun foo() { f() } } 

Отсюда вы можете передать эту функцию конструктору в качестве ссылки на метод:

 fun bar() { println("this is bar") } val a = A(::bar) a.foo() // this is bar 

Или как лямбда:

 val a = A({ println("this is the lambda") }) 

И вы даже можете сделать обычный синтаксический сахар для лямбда, который является последним параметром функции (хотя это немного дико):

 val a = A { println("this is the lambda") } 

Пример реального мира можно наблюдать в SynchronizedLazyImpl , класс, поддерживающий lazy делегатов.

 public fun <T> lazy(lock: Any?, initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer, lock) 

Когда мы используем val x by lazy {...} , initializer , передаваемый как лямбда, фактически хранится как свойство в экземпляре SynchronizedLazyImpl и вызывается позже, когда к нему обращается соответствующий val x .

Если у вас есть несколько объявлений конструкторов, вы можете использовать это

 ... private var listener : (() -> Unit)? = null constructor(context: Context, listener: (() -> Unit)?) : this(context){ this.listener = listener } constructor(context: Context) : super(context, attrs = null) ...