从this answer开始,我知道我可以从超类创建一个子类的实例。然而,我无法弄清楚如何从超类中创建子类的数组。
借鉴上面的例子,到目前为止,这是我最好的镜头:
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
返回一系列ScientificCalculators?
答案 0 :(得分: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() }
}
}
答案 1 :(得分:2)
你走在正确的轨道上,但你犯了一些错误。
首先,您需要返回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())