2016-01-17 13 views
3

在科特林我有这样的功能,包装一个交易:获取访问实例中的包装功能

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

我怎样才能在调用代码访问realmInstance

+0

几乎相同的代码存在于这个问题:http://stackoverflow.com/questions/34797366/in-kotlin-how-do-i-add-extension-methods-to-another-class-but-only-visible-in并在接受的答案中解释http ://stackoverflow.com/a/34797367/3679676事务本身包装代码。 –

回答

2

其他答案正确地演示了如何将RealmInstance对象传递给lambda。此外,还可以使整个功能的扩展功能,这使得调用点位漂亮:

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

调用现场看起来就像这样:

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

这里最简单的解决方案是让code一个function with receiver

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

内,你通过为code,你将能够使用this引用RealmInstance,并给其成员直接使用,就好像里面拉姆达一个成员函数。

打电话realmInstance.code()只是拨打code与通过realmInstance作为接收器。

+0

使整个功能成为扩展功能甚至更好。 –

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

Th由于Kotlin的Function Literals with Receiver使得上述技术成为可能,所以可以在lambda函数体内设置集合this实例(接收器)。它可以轻松构建重新组合Groovy或Ruby的类型安全构建器。

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