Получение доступа к экземпляру в функции обертки

В Kotlin у меня есть эта функция для переноса транзакции:

fun wrapInTransaction(code: () -> Unit) { realmInstance.beginTransaction(); code.invoke() realmInstance.commitTransaction(); } 

Как я могу получить доступ к realmInstance в вызываемом коде?

В других ответах правильно показано, как передать объект RealmInstance в лямбда. Кроме того, вы можете сделать всю функцию функцией расширения, которая делает сайт вызова немного красивее:

 fun Realm.wrapInTransaction(code: Realm.() -> Unit) { //this is implicit beginTransaction(); code() commitTransaction(); } 

Сайт вызова будет выглядеть так:

 Realm.getInstance(this).wrapInTransaction { createObject(User.class) } 

Легкое решение здесь – сделать code функцией с приемником :

 fun wrapInTransaction(code: Realm.() -> Unit) { realmInstance.beginTransaction(); realmInstance.code() realmInstance.commitTransaction(); } 

Внутри лямбда, которую вы передаете в качестве code вы сможете использовать this для ссылки на RealmInstance и использовать его члены напрямую, как внутри функции-члена.

Вызов realmInstance.code() – это просто вызов code с передачей realmInstance в качестве получателя.

Измените функцию wrapInTransaction чтобы принять метод расширений в realmInstance например:

 fun wrapInTransaction(code:Realm.() -> Unit){ realmInstance.beginTransaction(); realmInstance.code() realmInstance.commitTransaction(); } 

Затем вы можете использовать его так:

 wrapInTransaction { println("realm instance is $this, instanceId: $instanceId") } 

Где для примера Realm выглядит так:

 class Realm { val instanceId = 42 fun beginTransaction() { } fun commitTransaction() { } } 

Вышеупомянутая методика возможна благодаря функциям Литерализма Котлина с приемником, которые позволяют установить this экземпляр (приемник) в тело лямбда-функции. Это позволяет легко создавать безопасные строители типа, которые собирают их из Groovy или Ruby.

Этот ответ дает больше образцов по технике.