返回Self类型的数组

时间:2015-09-21 16:16:53

标签: ios swift

我在运行时在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”版本,请成为我的客人。无法帮助自己认为可能有更好的方法来做到这一点,但无法弄清楚如何做到这一点。

2 个答案:

答案 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()]
}