一系列略有不同的泛型

时间:2018-02-21 20:04:20

标签: swift generics

我有一个采用泛型类的类,它必须继承自类WorldObject

class WorldObjectsProvider<WorldObjectType: WorldObject> 

该类将创建类WorldObjectType的对象并在一个函数中返回它们。现在我想创建一个这样的类数组(WorldObjectsProvider),但我希望这个数组能够保留许多不同类型的泛型类WorldObjectsProvider,例如:

class TestObject: WorldObject { }
let providers: [WorldObjectsProvider<WorldObject>] = [WorldObjectsProvider<WorldObject>(), WorldObjectsProvider<TestObject>()]

一般来说,我认为这可能是可能的,因为所有泛型类型都应该从WorldObject继承。这可以通过将所有值作为对基类WorldObject的引用返回来工作。但我想这对于仿制药来说可能太过分了。有没有办法创建这样的数组?

1 个答案:

答案 0 :(得分:1)

Swift泛型类型在其泛型参数方面是不变的,这意味着MyGeneric<A>MyGeneric<B>不兼容,即使A: B也是如此。

话虽这么说,如果你需要使用两种不同的泛型,你需要两个泛型的共同点。类型橡皮擦是可能的解决方案之一:

struct AnyProvider<T: WorldObject> {
    init<U: WorldObject>(_ provider: WorldObjectsProvider<U>) { }
}

let providers: [AnyProvider<WorldObject>] = [AnyProvider(WorldObjectsProvider<WorldObject>()), AnyProvider(WorldObjectsProvider<TestObject>())]

这将允许您在同一集合中使用多种类型的泛型,前提是它们具有共同点。缺点是橡皮擦类型可能需要模仿和转发原始类型的所有公共方法。

例如,如果原始提供商使用func someProviderMethod()方法,那么AnyProvider也必须声明它:

struct AnyProvider<T: WorldObject> {
    private let _someProviderMethod: () -> Void

    init<U: WorldObject>(_ provider: WorldObjectsProvider<U>) {
        _someProviderMethod = provider.someProviderMethod
    }

    func someProviderMethod() {
        _someProviderMethod()
    }
}