在我的應用程式中,我想做這樣的事情:
在我的應用程式中,我想做這樣的事情。
interface Binder<in VB: ViewBinding, in T: Any> /span>{
fun bind(binding。VB, item: T)
}
class TypeInfoMap{
val map = mutableMapOf<Class<out Any>, Binder<ViewBinding, Any> >()
inline fun <reified VB: ViewBinding, reified T: Any> put(binder: Binder<VB, T>) {
map[T::class.java] = binder as Binder<ViewBinding, Any> // warning unchecked castinline fun <reified VB: ViewBinding, reified T: Any> get(cls: Class<T>): Binder<VB, T> {
return map[cls] as? Binder<VB, T> ?: throw IllegalStateException() /span> no warning ?
}
}
我在put函式中得到了警告unchecked cast。這是為什么呢?我為通用型別宣告了上界,這里的轉換不應該是正常的嗎?另外,即使我不行內該函式,get函式中的cast也沒有產生任何警告。我本以為我會在這里得到一個警告,實際上我很驚訝我沒有得到一個警告。
在Kotlin中是否有一種方法可以在沒有警告的情況下撰寫所有這些內容?我想這就是reified的作用。
uj5u.com熱心網友回復:
首先,從Binder<VB, T>到Binder<ViewBinding, Any>的鑄造是不正確的。如果binder被定義為Binder<VB, T>,你可以用一個VB實體呼叫binder.bind(),但是不能用不是VB的ViewBinding實體。所以一個Binder<VB, T>不是一個Binder<ViewBinding, Any>。
其次,unchecked cast的警告并不是關于cast是否有效。它是關于如果型別不正確,你不會在運行時得到一個ClassCastException的事實。這就是為什么它是危險的。
你可能不會在get()方法中得到一個未檢查的投射警告,因為無論如何投射總是有效的:一個Binder<ViewBinding, Any>總是一個Binder<VB, T>,鑒于Binder的差異性以及VB和T的宣告父型別。
在Kotlin中是否有辦法在沒有警告的情況下撰寫所有這些內容?我想這就是reified的作用。
reified允許在運行時訪問通用型別,但只允許訪問reified函式的型別。因此,舉例來說,他們允許你在不明確傳遞的情況下獲得某個實體的KClass。然而,你所使用的內部映射在運行時仍然不會給出關于你過去在其中放入了什么的資訊。
你能做的最好的事情就是忽略未選中的投射警告,因為你將無法在運行時知道映射中包含的通用型別。然而,如果你讓map私有化,你就有一個更安全的型別保護方法,因為你可以控制你在其中放入的內容:
class TypeInfoMap {
private val map = mutableMapOf<Key<*, *>, Binder<*, *> >()
class Key<VB : ViewBinding, T : Any>(
val bindingClass: KClass<VB>。
val valueClass: KClass<T>。
)
fun <VB : ViewBinding, T : Any> put(key。Key<VB, T> , binder: Binder<VB, T>) {
map[key] = binder
}
@Suppress("UNCHECKED_CAST") //type are guaranteed by put()
fun <VB : ViewBinding, T : Any> get(key: Key<VB, T>): Binder<VB, T> {
val binder = map[key] ? : error("沒有找到${key.bindingClass}型別的系結,用于${key.valueClass}"/span>)
return binder as Binder<VB, T>
}
inline fun <reified VB: ViewBinding, reified T: Any> put(binder: Binder<VB, T>) {
put(Key(VB::class, T::class), binder)
}
inline fun <reified VB: ViewBinding, reified T: Any> get(): Binder<VB, T> = get(Key(VB: :class, T::class))。
然后你可以安全地使用它與漂亮的重化型別:
。val infoMap = TypeInfoMap()
val someBinder: Binder<MyViewBinding, MyType> = createSomeBinderSomewhere()
infoMap.put(someBinder)
//在這里保證型別(如果沒有找到這些型別的系結,則運行時出錯)。
val binder = infoMap.get<MyViewBinding, MyType>()
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/318593.html
標籤:
上一篇:如何找到以下HTML的元素?
下一篇:如何創建一個通用結構?
