不能在 swift 中的数组类型的扩展函数中使用数组初始值设定项

问题描述 投票:0回答:1

使用 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 swift-extensions
1个回答
0
投票

通过查看更详细的错误信息:

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)

就是说,我不确定这是不是故意的。这种行为对你我来说肯定是出乎意料的,但我也能理解为什么它会这样。你在一个扩展中,其中

Element
类型参数毕竟等同于
Int
Element
类型被自动推断为
Int
,类似于以下情况:

extension [Int] {
    func foo() -> Array { // just writing "Array" works, no need to say Array<Int>
        self
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.