2016-01-17 14 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提供了該技術的更多樣本。