簡體   English   中英

Kotlin 泛型 - 遞歸泛型 - 轉換擦除類型的實例失敗

[英]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東西,但編譯器不知道:(

現在想象itEvilImplementation it.objectPool.releaseObject會接受一個Implementation ,但你給它一個EvilImplementation

無論如何,我認為您需要重新考慮您的設計,因為 Kotlin 不像其他語言那樣支持Self

另請參閱Java 中的類似問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM