使用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)
}
2条答案
按热度按时间qvtsj1bj1#
查看更详细的错误消息:
Swift认为你正在创建一个
Array<Int>
。如果只指定泛型类型参数,它将按预期工作:
这是问题SR-1789的一个示例。
通常,当你在泛型类型的类型声明/扩展中时,你可以使用没有泛型参数的类型,类型参数将被推断为你声明的类型参数。就像在这些情况下:
或者,
但是,这个功能似乎太“咄咄逼人”了,从某种意义上说。
qojgxg4l2#
Sweeper的回答描述了你遇到的问题,但这不是一个bug。这只是语言的工作方式。在泛型类型的定义或扩展中,该类型的名称指的是专用版本,而不是泛型版本。插图:
(
Array
在这方面并不特殊;您应该编辑问题标题。)虽然
.init
不适合您的用例,但它通常是推断正确类型的好解决方案:编译,而使用非专用化类型的名称将不会:
避免显式指定 * 占位符类型 * 的另一种方法是使用 *type占位符 *:
您可以选择
Array<String>
、[String]
、Array<_>
和[_]
。