我在运行时在Swift中找出一种返回特定动态类类型实例数组的方法。
我成功编译并测试了这个版本,该版本返回一个类的单个实例:
class Generic {
class func all() -> Self {
return self.init()
}
required init() {
}
}
class A: Generic {
}
let a = A.all() // is of type A
这里的挑战是进行编译以允许all
函数的原型如下:class func all() -> [Self]
(即返回一个实例数组,使用子类,没有任何强制转换)。
class Generic {
class func all() -> [Self] {
return [self.init()]
}
required init() {
}
}
class A: Generic {
}
let a = A.all() // won't compile
我可以使用Generic
返回class func all() -> [Generic]
个实例数组,但这需要使用as!
进行额外投射以获得正确的类型A
。我想在类A
的上下文中使用begin并使用Self
关键字,让编译器推断出“真实”类型。你们认为这有可能吗?
似乎只能返回单个实例,而不是数组。
编辑:使用AnyObject
让它工作。更好,但不是最佳,因为它需要强制转换为正确的类型。
class Generic {
class func all() -> [AnyObject] {
return [self.init()]
}
required init() {
}
}
class A: Generic {
}
let a = A.all() as! [A]
谢谢!
PS:使用泛型或协议/协议扩展来执行此操作的任何其他方法也是一种选择。如果您有更“Swifty”版本,请成为我的客人。无法帮助自己认为可能有更好的方法来做到这一点,但无法弄清楚如何做到这一点。
答案 0 :(得分:0)
不幸的是,似乎没有办法使用Self
执行此操作。 Self
无法在表达式中使用,因此不允许使用[Self]
或Array<Self>
。
但是,我认为您的用例完全有效,您应该将其作为错误重新编写。
答案 1 :(得分:0)
我能看到做这样的事情的唯一选择是使用协议而不是基类,如下所示:
protocol Generic {
func all() -> [Self]
init()
}
extension Generic {
func all() -> [Self] {
return [self.dynamicType.init()]
}
}
final class A : Generic {
}
A().all()
这样做有两个限制。首先,所有符合您协议的类都必须是最终的。其次,所有类必须显然实现协议中定义的init,否则我们将无法定义all
方法。
编辑:只要您不定义任何其他初始值设定项,您实际上不需要定义init
编辑2:我没有注意到您使用了类函数,您可以通过将func all() -> [Self]
替换为static func all() -> [Self]
和
func all() -> [Self] {
return [self.dynamicType.init()]
}
与
static func all() -> [Self] {
return [self.init()]
}