【问题标题】:Generalized type constraints with SwiftSwift 的广义类型约束
【发布时间】:2015-01-28 10:56:29
【问题描述】:

作为练习,我尝试在 Swift 中扩展 Array 以添加 sum() 成员函数。这应该是类型安全的,我希望只有在数组包含可以相加的元素时才能调用sum() 进行编译。

我尝试了一些类似这样的变体:

extension Array {

    func sum<U : _IntegerArithmeticType where U == T>() -> Int {
        var acc = 0
        for elem in self {
            acc += elem as Int
        }
        return acc
    }

}

这个想法是说,“好吧,这是一个泛型函数,泛型类型必须类似于Int,并且还必须与数组元素的类型T相同” .但是编译器抱怨:“相同类型的要求使泛型参数 U 和 T 等效”。没错,它们应该是,加上额外的约束T : _IntegerArithmeticType

为什么编译器不让我这样做?我该怎么做?

(我知道我应该稍后修复事物的相加方式以及返回类型究竟是什么,但我现在卡在类型约束上。)

【问题讨论】:

  • (目前)无法使用要求元素为受限类型的方法来扩展 Array。比较stackoverflow.com/questions/24938948/…stackoverflow.com/questions/25630476/…(两者都可能被视为重复)。
  • 你写了“(当前)”。有没有人听说它可能很快就会改变?
  • 认为,我在 devforums.apple.com 中读到过这是一个已知问题,将来可能会改变,但我不能 100% 确定。如果我再次找到它,我会给你链接。
  • 谢谢。我将发布我发现的最不坏的解决方法作为答案。

标签: swift type-constraints generics swift-extensions


【解决方案1】:

根据 Martin R 的评论,目前这是不可能的。在这种特殊情况下,我很想使用的东西是显式传递 T -&gt; Int 转换函数:

extension Array {

    func sum(toInt: T -> Int?) -> Int {
        var acc = 0
        for elem in self {
            if let i = toInt(elem) {
                acc += i
            }
        }
        return acc
    }

}

然后我可以写这样的东西:

func itself<T>(t: T) -> T {
    return t
}

let ss = ["1", "2", "3", "4", "five"].sum { $0.toInt() }
let si = [1, 2, 3, 4].sum(itself)

但是,必须传递显式函数。 (itself) 部分当然可以替换为{ $0 }。 (其他人已经调用了itself函数identity。)

请注意,当需要A -&gt; B? 时,可以传递A -&gt; B 函数。

【讨论】:

    猜你喜欢
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多