如何在Swift中编写通用工厂方法? [英] How to write generic factory method in swift?
问题描述
如果可能的话,我不确定如何写入调用其通用类型的构造函数的方法,该方法继承自通用已知基类< T:Base>创建T的某些实例,而不诉诸明确的工厂函数,即通过类型推断提供的所有铃声和哨子。
p>
//让MyPod和Boomstick带有通用基类(不重要)
class Base:Printable {
让价值:字符串; init(_ value:String){self.value =Base。 + value}
var description:String {return value}
}
class MyPod:Base {
init(_ value:String){super.init(MyPod。+值)}
}
类动臂:Base {
init(_ value:String){super.init(Boomstick。+ value)}
}
//问题:不知道如何在这里强制调用Boomstick(n)而不是Base(n)
func createSome< T:Base>() - >对于n中的1 ... 5 {
结果+ = T(toString(n))
} $,T [] {
var result = Array< T> b $ b返回结果
}
//这似乎很好。
//我期待着调用createSome< Boomstick>(){... result + = Boomstick(n)...
let objs:Boomstick [] = createSome()
/ / Prints:Base.1,Base.2,...没有多少希望Boomstick.1,Boomstick.2,...
println(objs)
一个显而易见的解决方案是将创建委托给调用者,但看起来很笨重:
func createSome< T>(工厂:(Int) - > T){...}
谢谢。
PS:是不是将createSome() - > Base []赋值给objs:Boomstick []类型的安全违规?
现在我没有关于为什么的答案,而是仅使用初始化程序定义协议似乎有效:
protocol A {
init(_ value:String)
}
您在所有类中实现此协议如下
class Base:Printable,A {
let val ue: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。+值)}
}
并使用 A
而不是 Base
在您的 createSome()
func
func createSome< T:A>() - > [T] {
var result = Array< T>()
for n in 1 ... 5 {
result + = T(toString(n))
}
返回结果
}
在运动场测试:
let objs:[Boomstick] = createSome()
objs [0]
并且它打印:
{valueBase.Boomstick.1 }
还尝试使用 MyPod
和 Base
并打印预期结果。
测试一下,让我知道它是否也适用于您。
I am not sure how to, if it's possible to, write method that calls constructor of it's generic type inheriting from common known base class < T:Base > to create some instances of T without resorting to explicit factory function i.e. with all bells and whistles provided by type inference.
Example that works in playground:
// 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)
One obvious solution is to delegate creation to caller, but that seems clunky:
func createSome<T>(factory : (Int)->T) { ... }
Thank you.
PS: Isn't assignment of createSome()->Base[] to objs:Boomstick[] type safety violation?
Right now I don't have an answer about the why, but defining a protocol with the initializer only seems to work:
protocol A {
init(_ value: String)
}
You implement this protocol in all classes as below
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) }
}
and use A
rather than Base
in your createSome()
func
func createSome<T : A>() -> [T] {
var result = Array<T>()
for n in 1...5 {
result += T(toString(n))
}
return result
}
Tested in playground:
let objs : [Boomstick] = createSome()
objs[0]
and it prints:
{value "Base.Boomstick.1"}
Also tried using MyPod
and Base
and it printed the expected results.
Test it out and let me know if it works for you as well.
这篇关于如何在Swift中编写通用工厂方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!