如何在swift中编写通用工厂方法?

Ada*_*dam 5 generics factory type-inference swift

我不知道如果有可能,如何编写调用它的泛型类型的构造函数的方法继承自公共已知的基类<T:Base>来创建T的一些实例而不依赖于显式工厂函数,即所有的钟声和口哨由类型推断提供.

在游乐场中工作的示例:

// Let there be classes MyPod and Boomstick with common Base (not important)
class Base : Printable {
    let value : String; init(_ value : String) { self.value = "Base." + value }
    var description: String { return value }
}
class MyPod : Base {
    init(_ value: String) { super.init("MyPod." + value) }
}
class Boomstick : Base {
    init(_ value: String) { super.init("Boomstick." + value) }
}
// PROBLEM: do not know how to force call of Boomstick(n) instead of Base(n) in here
func createSome<T : Base>() -> T[] {
    var result = Array<T>()
    for n in 1...5 {
        result += T(toString(n))
    }
    return result
}
// This seems to be fine. 
// I was expecting call of createSome<Boomstick>() { ... result += Boomstick(n) ...
let objs : Boomstick[] = createSome() 
// Prints: Base.1, Base.2, ... not much wished Boomstick.1, Boomstick.2, ...
println(objs)
Run Code Online (Sandbox Code Playgroud)

一个明显的解决方案是将创建委托给调用者,但这似乎很笨重:

func createSome<T>(factory : (Int)->T) { ... }
Run Code Online (Sandbox Code Playgroud)

谢谢.

PS:是不是将createSome() - > Base []分配给objs:Boomstick []类型安全违规?

Ant*_*nio 5

现在我没有关于原因的答案,但是使用初始化程序定义协议似乎只能起作用:

protocol A {
    init(_ value: String)
}
Run Code Online (Sandbox Code Playgroud)

您可以在所有类中实现此协议,如下所示

class Base : Printable, A {
    let value : String;
    init(_ value : String) { self.value = "Base." + value }
    var description: String { return value }
}

class MyPod : Base, A {
    init(_ value: String) { super.init("MyPod." + value) }
}

class Boomstick : Base, A {
    init(_ value: String) { super.init("Boomstick." + value) }
}
Run Code Online (Sandbox Code Playgroud)

并使用A而不是Base你的createSome()功能

func createSome<T : A>() -> [T] {
    var result = Array<T>()
    for n in 1...5 {
        result += T(toString(n))
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)

在操场上测试:

let objs : [Boomstick] = createSome()
objs[0]
Run Code Online (Sandbox Code Playgroud)

它打印:

{value "Base.Boomstick.1"}
Run Code Online (Sandbox Code Playgroud)

也尝试使用MyPodBase它打印预期的结果.测试一下,让我知道它是否也适合你.