首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从超类创建子类实例数组

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

Stack Overflow用户
提问于 2015-03-05 22:22:32
回答 2查看 436关注 0票数 0

this answer中,我知道我可以从超类创建子类的实例。然而,我不知道如何从超类创建子类数组。

根据上面的例子,下面是我迄今为止最好的尝试:

代码语言:javascript
复制
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]'

如何从ScientificCalculators返回Calculator.createMultiple数组

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-05 22:37:35

你走在正确的轨道上,但你犯了一些错误。

首先,您需要返回一个T数组,而不仅仅是一个元素。因此,您需要将返回类型从T更改为[T]

代码语言:javascript
复制
class func createMultiple<T:Calculator>(num: Int) -> [T] {

此外,您也可以使用T初始化子类的新实例,如下所示:

代码语言:javascript
复制
var calculators:[T] = [T]()

但其他部分是正确的。所以你的最后一种方法是这样的:

代码语言:javascript
复制
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
    }
}

编辑,如果你使用SWIFT1.2,你就不用再和subclass打交道了,你可以用T代替,就像空速答案中显示的那样。

代码语言:javascript
复制
calculators.append(T())
票数 2
EN

Stack Overflow用户

发布于 2015-03-05 22:29:47

编辑:在最新的SWIFT1.2测试版中,这种行为似乎发生了变化。您不需要使用T.selfT是要创建的类型。但是,如果您使用的是1.1,它似乎不能工作(即使T是子类型,它也会创建超级类型),并且使用元类型创建类型可以解决这个问题。关于1.1版本,请参见答案的结尾。

你不需要和subclass: T.Type = T.self捣乱。只需使用T --它本身就是类型(确切地说,是调用方指定的任何类型的占位符):

代码语言:javascript
复制
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循环:

代码语言:javascript
复制
class func createMultiple<T: Calculator>(num: Int) -> [T] {
    return map(0..<num) { _ in T() }
}

如果仍然使用SWIFT1.1,则需要使用T.self来解决子类型未正确创建的问题:

代码语言:javascript
复制
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() }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28888946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档