从Swift中的数组转换为右泛型

ph1*_*lb4 14 arrays generics swift

我有一个叫做的协议Composite.

该协议有一个数组 composites: [Composite]

我也有一个通用的子类 GenericSubclass<T>: Composite

迭代数组时,我能想到的最好看起来像这样:

for item in composites {
    if let item = item as? GenericSubclass<A> {
        let sc = SomeOtherClass<A>
    } else if let item = item as? GenericSubclass<B> {
        let sc = SomeOtherClass<B>
    } //and so on...
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在GenericSubclass没有指定Generic 的情况下获得保留?在我的用例中,我完全不需要了解T.我只需要实例化具有相同泛型类型的另一个类.

任何帮助深表感谢.

Dav*_*ton 7

目前尚不清楚你要用你所选择的"通用"(双关语)类名来完成什么.我认为没有办法直接完成你想要的东西.也就是说,你不能把它留作通用,T因为编译器需要一些方法来确定T在运行时将使用什么.

但是,解决该问题的一种方法是将API提升到Composite协议中:

protocol Composite {
    var composites: [Composite] { get set }
    func otherClass() -> OtherProtocol
}

protocol OtherProtocol { }

class GenericSubclass<T>: Composite {
    var composites: [Composite] = []

    func otherClass() -> OtherProtocol {
        return SomeOtherClass<T>()
    }
}

class SomeOtherClass<T>: OtherProtocol {}
Run Code Online (Sandbox Code Playgroud)

所以现在当你实现你的循环时,你可以依赖这样一个事实,因为每个元素都是a Composite,你知道它必须OtherProtocol通过该otherClass()方法提供一个实例:

var c = GenericSubclass<Int>()
c.composites = [GenericSubclass<Double>(), GenericSubclass<Int>(), GenericSubclass<Character>()]

for item in c.composites {
    let sc = item.otherClass()
    print(sc)
}
Run Code Online (Sandbox Code Playgroud)

或者,如果只GenericSubclass应该售卖OtherProtocol,您可以制作返回类型Optional并为以下所有其他实现定义扩展Composite:

protocol Composite {
    var composites: [Composite] { get set }
    func optionalClass() -> OtherProtocol?
}

extension Composite {
    func optionalClass() -> OtherProtocol? {
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)