首页 > 解决方案 > Swift 泛型子类型总是返回父级

问题描述

我正在尝试做一个泛型容器池,但是我发现当尝试从父类回收时,泛型推断无法正确解决,我只得到父类型而不是具体类型

一个例子:

Enemy : Poolable {


   func die() {
       containerPool.recycle(self)
   }

}

Enemy2 : Enemy {

}


containerPool.obtain(Enemy2.self).die() //Crash with Could not cast value of type Pool<Enemy2> to Pool<Enemy>

//容器池回收方法:

import Foundation

protocol Poolable {
    init()
    func onRecycled()
    func willBeObtained()
}

class Pool<T:Poolable> {
    
    var objects:[T] = []
    
    init(initialSpawn:Int = 0){
        for _ in 0...initialSpawn {
            objects.append(T.init())
        }
    }
    
    func obtain() -> T {
        if objects.count > 0 {
            let object = objects.removeFirst()
            object.willBeObtained()
            return object
        }
        let object = T.init()
        object.willBeObtained()
        return object
    }
    
    func recycle(_ object:T) {
        object.onRecycled()
        objects.append(object)
    }
    
}

class ContainerPool {
    
    var pools:[String:Any] = [:]
    
    func obtain<T:Poolable>() -> T {
        pool(for:T.self).obtain()
    }
    
    func obtain<T:Poolable>(_ type:T.Type) -> T{
        pool(for:type).obtain()
    }
    
    func recycle<T:Poolable>(_ object:T) {
        let concreteType = type(of: object)
        pool(for: concreteType).recycle(object)
    }
    
    func pool<T:Poolable>(for type:T.Type, initialSpawn:Int = 10) -> Pool<T> {
        let typeString = "\(type)"
        if let pool = pools[typeString] as? Pool<T> {
        //if let pool = pools[typeString] {
            return pool
        }
        let pool = Pool<T>(initialSpawn:initialSpawn)
        pools[typeString] = pool
        return pool
    }
        
    func preload<T:Poolable>(type:T.Type, size:Int = 20){
        let _ = pool(for: type, initialSpawn: size)
    }
    
}

typeStrings 总是正确的,我进入 let pool 的池是正确的,但我不能将它转换为 Enemy2,因为它认为 T 是 Enemy ......

有没有办法解决它?

标签: swiftgenericspool

解决方案


推荐阅读