举个例子来解释这个问题会更容易一些。例如,考虑这个简单的泛型类:
final class GenericClass<T> {
private let parameter: T
init(parameter: T) {
self.parameter = parameter
}
}
init
我想在扩展中添加一个空值,当T
为任意值时Array
(甚至是Collection
,但这对我的情况并不重要)。我想要这样的东西,但它无法编译:
// Reference to generic type 'Array' requires arguments in <...>
extension GenericClass where T: Array {
convenience init() {
// Cannot convert value of type '[Any]' to expected argument type 'T'
self.init(parameter: [])
}
}
如何向 添加通用参数Array
?此语法不起作用:
extension GenericClass<U> where T: Array<U> { // Cannot find type 'U' in scope
convenience init() {
self.init(parameter: [U]()) // Cannot call value of non-function type '[Any]'
}
}
(T == Array<U>
也不起作用。)
有什么方法可以实现我所描述的内容?我真的想避免为我需要的每种元素类型声明单独的扩展(当然下面的代码运行得很好):
extension GenericClass where T == [Int] {
convenience init() {
self.init(parameter: [])
}
}
如果你特别需要
Array
,你可以将额外的类型参数添加U
到init
. 而不是extension GenericClass<U>
:如果所有的
init
需求都是能够转换[]
为T
.T
那就可以是ExpressibleByArrayLiteral
.如果
[]
你特指“一个空集合”,那么你应该要求T
。RangeReplaceableCollection
该协议提供了一个init
创建空集合的协议。这并不
ExpressibleByArrayLiteral
意味着类型是集合。OptionSet
例如,不是Collection
,但它是ExpressibleByArrayLiteral
。