Swift扩展和'Element'显式初始化

时间:2017-10-31 19:14:22

标签: swift extension-methods

我想知道是否有其他方法可以在Swift扩展中显式初始化Element对象?

例如我想这样做,但非标称类型'Element'不支持显式初始化

extension Array where Element: Numeric {
    func findDuplicate() -> Int {
        guard self.count > 0 else { return -1 }
        let sum = self.reduce(0, +)
        let expectedSum = Element((self.count - 1) * self.count / 2)
        return sum - expectedSum
    }
}

当然如果我在expectedSum赋值中删除强制元素转换并让编译器使用Int我得到一个错误比较sum(Element)和expectedSum(Int)

我可以轻松地将我的扩展程序与Element == Int一起使用,但当然这不再是通用的。

任何提示?

1 个答案:

答案 0 :(得分:4)

使用init?(exactly:)将整数转换为Numeric类型。考虑到青少狮的建议:

extension Array where Element: Numeric {
    func findDuplicate() -> Element? {
        guard !isEmpty else { return nil }
        let sum = self.reduce(0, +)
        guard let expectedSum = Element(exactly: (count - 1) * count / 2) else { return nil }
        return sum - expectedSum
    }
}

另一方面,这似乎是一项编程任务 特别关于整数,然后它可能更有意义 将元素类型限制为BinaryInteger(并使用Int 用于中间计算以避免溢出):

extension Array where Element: BinaryInteger {
    func findDuplicate() -> Element? {
        guard !isEmpty else { return nil }
        let sum = Int(reduce(0, +))
        let expectedSum = (count - 1) * count / 2
        return Element(sum - expectedSum)
    }
}

甚至是Element == Int