【问题标题】:Is it possible to define [Int] * Int using custom operator in Swift?是否可以在 Swift 中使用自定义运算符定义 [Int] * Int?
【发布时间】:2016-04-26 14:34:07
【问题描述】:

我想定义一个新的运算符,将数组[Int]的每个元素乘以Int,比如[3, 2, 10] * 10

但是,因为Int既不是协议也不是类(它是结构体),所以我首先定义了以下内容:

protocol Numeric {}
extension Int: Numeric {}
extension Double: Numeric {}
extension Float: Numeric {}

然后,我尝试定义运算符,例如:

func *<T: Numeric> (left: [T], right: T) -> [T] {
    var newArray: [T] = []
    for i in left {
        newArray.append(i * right)
    }

    return newArray
}

但是,这会吐出一个错误:Cannot convert value of type 'T' to expected argument type '[_]'

我不确定[_] 的类型是什么意思,我不期望,但我想问题出在我没有定义一个接受@987654331 的运算符@ 和T,在这种情况下都是Numeric

所以我定义了另一个运算符,比如:

func *<T: Numeric> (left: T, right: T) -> T {
    return left * right
}

然而,虽然这已经编译没有问题,运行时错误发生了很多很多static * infix &lt;A where ...&gt; (A, A) -&gt; A

我不确定为什么这个操作符被执行了这么多次,但现在我想知道是否可以首先定义一个自定义的* 操作符,尽管Int 确实已经有* 操作符已定义。

那么在 Swift 中是否还可以定义 [Int] * Int 运算符?

【问题讨论】:

    标签: swift operator-overloading operators


    【解决方案1】:

    你必须要求Numeric中的乘法运算 协议:

    protocol Numeric {
        func *(lhs: Self, rhs: Self) -> Self
    }
    

    否则newArray.append(i * right) 中的乘法是 未定义。

    你的

    func *<T: Numeric> (left: T, right: T) -> T {
        return left * right
    }
    

    (递归调用自身,导致堆栈溢出)就不需要了。

    新操作符本身的实现可以简化 (如已在现已删除的答案中所述)到

    func *<T: Numeric> (left: [T], right: T) -> [T] {
        return left.map { $0 * right }
    }
    

    【讨论】:

    • 哇,太棒了。好吧,我首先尝试使用 map 来定义它,但是在碰壁之后,我让它变得更简单,以确保问题不是来自 map。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2013-11-10
    • 2017-06-04
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2011-09-01
    相关资源
    最近更新 更多