[英]Kotlin Generics - recursive generic - casting the instance of erased type fails
當我遍歷 Sprite 列表並檢查它們是否實現 UsesObjectPool 時,由於類型擦除,我遇到了這些問題:
*如果我嘗試檢查它的類型,我會得到:
無法檢查已擦除類型的實例:UsesObjectPool
if(it is UsesObjectPool<Sprite>)
{
it.objectPool.releaseObject(it)
}
”必填參數Nothing,找到Sprite & UsesObjectPool:
if(it is UsesObjectPool<*>)
{
it.objectPool.releaseObject(it)
}
*如果我將它轉換為 UsesObjectPool,我會得到:
類型參數不在其范圍內。 預期:UsesObjectPool 發現:Sprite
if(it is UsesObjectPool<*>)
{
(it as UsesObjectPool<Sprite>).objectPool.releaseObject(it)
}
泛型類和接口:
interface UsesObjectPool<T> where T :UsesObjectPool<T>, T : Sprite
{
val objectPool: BaseObjectPool<T>
}
abstract class BaseObjectPool<T> where T : UsesObjectPool<T>, T : Sprite
{
fun releaseObject(instance: T)
{
//Implementation
}
}
這里的問題是您實際上並不是說T
應該是實現類型(在某些語言中稱為Self
)。 就 Kotlin 編譯器而言, T
可以是實現UsesObjectPool<T>
任何其他類型。 這就是為什么你不能將it
傳遞給releaseObject
。
下面是一個例子:
class EvilObjectPool<T>: BaseObjectPool<T>() where T : UsesObjectPool<T>, T : Sprite
class Implementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
class EvilImplementation : Sprite(), UsesObjectPool<Implementation> {
override val objectPool: BaseObjectPool<Implementation>
get() = EvilObjectPool()
}
請注意,這會編譯. 通常我們作為人類認識到這種“自綁定泛型”模式,並且永遠不會寫類似EvilImplementation
東西,但編譯器不知道:(
現在想象it
是EvilImplementation
。 it.objectPool.releaseObject
會接受一個Implementation
,但你給它一個EvilImplementation
!
無論如何,我認為您需要重新考慮您的設計,因為 Kotlin 不像其他語言那樣支持Self
。
另請參閱Java 中的類似問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.