如何在Swift中编写通用工厂方法? [英] How to write generic factory method in swift?

查看:102
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆