使用Swift 5.7.2和Xcode 14.2我试图写一个扩展函数到一个特定类型的数组,即[MyClass]
。在函数内部,我希望能够使用Array()
初始化器将集合转换为数组,但我不能。我得到以下错误:No exact matches in call to initializer
.
为了模拟这个问题,我用下面的代码创建了一个小游乐场,我只是尝试扩展[Int]
。此外,我意识到这只是在扩展数组时出现的问题,因为当我只扩展Int
类型时不会出现错误。
我非常好奇为什么会发生这种情况,我希望有人能帮我弄清楚。这很可能有一个合乎逻辑的解释。
扩展[Int](不工作)
extension [Int] {
func foo() {
let strSet = Set(["a", "b", "c", "a"])
let strArray = Array(strSet) // No exact matches in call to initializer
print(strArray)
}
func bar() {
let strSet = Set(["a", "b", "c", "a"])
let strArray = strSet.map {$0}
print(strArray)
}
}
扩展Int(工作正常)
extension Int {
func foo() {
let strSet = Set(["a", "b", "c", "a"])
let strArray = Array(strSet) // Works fine
print(strArray)
}
func bar() {
let strSet = Set(["a", "b", "c", "a"])
let strArray = strSet.map {$0}
print(strArray)
}
}
不是一个扩展(工作正常)
func foo() {
let strSet = Set(["a", "b", "c", "a"])
let strArray = Array(strSet)
print(strArray)
}
查看更详细的错误消息:
Swift.Array:3:23: note: candidate requires that the types 'Int' and 'String' be equivalent (requirement specified as 'Element' == 'S.Element')
@inlinable public init<S>(_ s: S) where Element == S.Element, S : Sequence
^
Swift.RangeReplaceableCollection:3:23: note: candidate requires that the types 'Int' and 'String' be equivalent (requirement specified as 'Self.Element' == 'S.Element')
@inlinable public init<S>(_ elements: S) where S : Sequence, Self.Element == S.Element
似乎Swift认为你试图创建一个Array<Int>
.
如果您只指定泛型类型参数,它将按预期工作:
let strArray = Array<String>(strSet)
这是issue SR-1789的一个实例。
通常,当你在泛型类型的类型声明/扩展中,你可以使用没有泛型参数的类型,并且类型参数将被推断为你声明的类型参数。就像在这些情况下:
extension [Int] {
func foo() -> Array { // just writing "Array" works, no need to say Array<Int>
fatalError()
}
}
或
class Foo<T> {
func foo() -> Foo { // just writing "Foo" works, no need to say Foo<T>
fatalError()
}
}
然而,从某种意义上说,这个功能似乎太"咄咄逼人"了。