根据这个答案,我知道我可以从超类创建子类的实例。然而,我不知道如何从超类创建子类的数组。
根据上面的例子,这里是我迄今为止最好的镜头:
class Calculator {
func showKind() { println("regular") }
required init() {}
}
class ScientificCalculator: Calculator {
let model: String = "HP-15C"
override func showKind() { println("(model) - Scientific") }
required init() {
super.init()
}
}
extension Calculator {
class func createMultiple<T:Calculator>(num: Int) -> T {
let subclass: T.Type = T.self
var calculators = [subclass]()
for i in 0..<num {
calculators.append(subclass())
}
return calculators
}
}
let scis: [ScientificCalculator] = ScientificCalculator.createMultiple(2)
for sci in scis {
sci.showKind()
}
对于该代码,行var calculators = [subclass]()
显示错误Invalid use of '()' to call a value of non-function type '[T.Type]'
。
如何从Calculator.createMultiple
返回一组科学计算器?
你走在正确的轨道上,但你犯了一些错误。
首先,您需要返回一个T
数组,而不仅仅是一个元素。因此,您需要将返回类型从T
更改为[T]
:
class func createMultiple<T:Calculator>(num: Int) -> [T] {
此外,您还可以使用T
初始化子类的新实例,如下所示:
var calculators:[T] = [T]()
但其他部分是正确的。所以你们最后的方法是这样的:
extension Calculator {
class func createMultiple<T:Calculator>(num: Int) -> [T] {
let subclass: T.Type = T.self
var calculators = [T]()
for i in 0..<num {
calculators.append(subclass())
}
return calculators
}
}
编辑如果你使用Swift 1.2,你就不必再处理subclass
了,你可以使用T
,就像Airspeeds答案中所示的那样。
calculators.append(T())
EDIT:在最新的Swift 1.2测试版中,这种行为似乎发生了变化。您不应该使用T.self
。T
是您要创建的类型。但是,如果使用1.1,它似乎不起作用(即使T
是子类型,它也会创建超类型),使用元类型创建类型可以解决这个问题。有关1.1版本,请参见答案末尾。
你不需要惹subclass: T.Type = T.self
。只需使用T
——它本身就是类型(或者更确切地说,是调用者指定的任何类型的占位符):
extension Calculator {
// you meant to return an array of T, right?
class func createMultiple<T: Calculator>(num: Int) -> [T] {
// declare an array of T
var calculators = [T]()
for i in 0..<num {
// create new T and append
calculators.append(T())
}
return calculators
}
}
顺便说一句,你可以用map替换for
循环:
class func createMultiple<T: Calculator>(num: Int) -> [T] {
return map(0..<num) { _ in T() }
}
如果您仍然使用Swift 1.1,则需要使用T.self
来解决子类型未正确创建的问题:
extension Calculator {
// only use this version if you need this to work in Swift 1.1:
class func createMultiple<T: Calculator>(num: Int) -> [T] {
let subclass: T.Type = T.self
return map(0..<num) { _ in subclass() }
}
}