是否可以在Swift中使用自定义运算符定义[Int] * Int?

时间:2016-04-26 14:34:08

标签: swift operator-overloading operators

我想定义一个新运算符,并将数组[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 '[_]'

我不确定类型[_]的含义是什么,我不是期望,但我想问题来自于我没有定义的运算符TT,在这种情况下都是Numeric

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

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

然而,虽然编译时没有遇到任何问题,但运行时错误发生在很多static * infix <A where ...> (A, A) -> A上。

enter image description here

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

那么仍然可以在Swift中定义[Int] * Int运算符吗?

1 个答案:

答案 0 :(得分:2)

您必须在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 }
}