如何从超类创建子类的实例数组



根据这个答案,我知道我可以从超类创建子类的实例。然而,我不知道如何从超类创建子类的数组。

根据上面的例子,这里是我迄今为止最好的镜头:

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.selfT是您要创建的类型。但是,如果使用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() }
    }
}

最新更新