我的專案中有一個聽眾。它被分配給drawerLayout。我想在 lambda 函式中洗掉它并立即(按順序)將其設為空。是否可以為空 T 或this在通用函式的末尾。
這是我的代碼:
// Usage
actionBarListener?.let {
drawerLayout.removeDrawerListener(it) // remove listener
actionBarListener = null // null it
}
// Usage expected
actionBarListener.releaseAndSetNull {
drawerLayout.removeDrawerListener(it) // remove listener and null it
}
// Generic
fun <T> T?.releaseAndSetNull(block: (T?) -> Unit) = apply {
this?.apply { block.invoke(this) }
this = null // Error: variable expected
}
uj5u.com熱心網友回復:
正如 Ivo Beckers 所說,此功能僅適用于vars,即KMutableProperty0<T>. 所以你可以在 上寫一個擴展KMutableProperty0<T?>,并使用反射來設定它,如果你不介意使用反射,那就是。
inline fun <T: Any> KMutableProperty0<T?>.releaseAndSetNull(block: (T?) -> Unit) {
block(this.get())
this.set(null)
}
// or if you don't want the block to be called if the property is null:
inline fun <T: Any> KMutableProperty0<T?>.releaseAndSetNull(block: (T) -> Unit) {
this.get()?.run(block)
this.set(null)
}
然后假設你有一個屬性:
var foo: Int? = 10
你可以做:
::foo.releaseAndSetNull { println("Foo: $it") }
// or if foo belongs to someObject
someObject::foo.releaseAndSetNull { println("Foo: $it") }
查看生成的位元組碼,實作方式(可能會發生變化)是屬性參考以這種方式參考的每個唯一屬性都會導致生成內部類。然后,內部類將擁有能夠以很少的額外成本完成作業get的set方法——因為它們可以直接設定正確的屬性。所以真正的主要成本是產生的額外內部類。
uj5u.com熱心網友回復:
我能想到幾個為什么這永遠行不通的原因。
首先,通用函式不知道this是 avar還是val。而且這個功能只能在var
同樣,它不能知道它是否可以為空,這也是一個要求。
此外,它甚至可能不是呼叫函式的變數。
就像說你有
fun getActionBarListener() {
return actionBarListener
}
然后在其他地方你可以做
getActionBarListener().releaseAndSetNull {
drawerLayout.removeDrawerListener(it) // remove listener and null it
}
你希望它如何作業?
甚至匿名物件也可以呼叫這個函式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/435080.html
