访问包装函数中的实例

时间:2016-01-17 16:46:10

标签: kotlin

在Kotlin中,我有这个函数来包装一个事务:

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

如何在调用的代码中访问realmInstance

3 个答案:

答案 0 :(得分:3)

这里简单的解决方案是让code成为function with receiver

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

在作为code传递的lambda中,您将能够使用this来引用RealmInstance并直接使用其成员,就像在成员函数中一样。

致电realmInstance.code()只是通过code作为接收者来调用realmInstance

答案 1 :(得分:2)

其他答案正确演示了如何将RealmInstance对象传递给lambda。此外,您可以使整个功能成为一个扩展功能,使呼叫站点更漂亮:

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

通话网站将如下所示:

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

答案 2 :(得分:1)

更改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() {
    }
}

由于Kotlin的Function Literals with Receiver可以在lambda函数体中设置 this实例(接收者),因此上述技术是可行的。它可以很容易地构建从Groovy或Ruby重组的类型安全构建器。

This answer提供了更多关于该技术的样本。