2014-06-21 64 views
4

我不知道怎麼樣,如果有可能,編寫方法來調用它的構造函數的泛型類型從普通已知的基類繼承< T:基地>打造的T某些情況下不採取即與所有的鐘聲明確的工廠函數並通過類型推斷提供口哨聲。如何在swift中編寫泛型工廠方法?

例,在遊樂場工作:

// 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) 

一個顯而易見的解決方案是創建委託給調用者,但似乎笨拙:

func createSome<T>(factory : (Int)->T) { ... } 

謝謝。

PS:是不是createSome(分配) - >基礎[]到OBJ文件:火槍[]類型安全違規?

+0

可能重複的[Swift泛型不保留類型](http://stackoverflow.com/questions/26280176/swift-generics-not-preserving-type) – Lee

回答

4

現在我沒有對爲什麼一個答案,但定義與初始化協議只似乎工作:

protocol A { 
    init(_ value: String) 
} 

你實現所有的類此協議如下

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) } 
} 

,並在您createSome() FUNC使用A而不是Base

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

測試在遊樂場:

let objs : [Boomstick] = createSome() 
objs[0] 

和它打印:

{value "Base.Boomstick.1"} 

使用MyPodBase也試過和它打印的預期的結果。 測試一下,讓我知道它是否也適合你。

+0

這不再工作。見http://stackoverflow.com/questions/26280176/swift-generics-not-preserving-type – Lee

+0

這實際上是相當不錯的。甚至可以利用它:將基類提升爲協議=>減少繼承,更多表達看起來像什麼......謝謝! ...和該死的(第二篇文章)... :-D – Adam

+0

看看:https://gist.github.com/joshdholtz/251b02730edd52330cee –