Swift-创建后置和前缀运算符?

时间:2018-08-08 18:01:05

标签: swift operators

在数学中,通常将x的数量写为| x |。我想采用与我的代码类似的方法。我的尝试如下所示:

prefix operator |
postfix operator |

extension Int {
    lazy var absolute = false
    static prefix func | (right: Int) -> Int {
        assert(right.absolute, "Missed closing absolute value bar.")
        right.absolute = false
        if right < 0 {
            return -value
        }
        return value
    }
    static postfix func | (left: Int) -> Int {
        assert(!left.absolute, "Missed opening absolute value bar.")
        left.absolute = true
        return left
    }
}

(我认为这段代码不会编译,因为就我所知,您无法在扩展中添加存储的属性。它只是用来演示我的尝试。我将此功能添加到了自定义类型中。)

尽管这对我来说似乎是一个非常糟糕的解决方案,但是这段代码的另一个问题是,即使我忘记了开头的小节,它也不会引发任何错误。断言只会在我忘记上一次数量函数调用中的开始条后才调用另一个数量函数而中断正在运行的程序。

让我知道您是否有更好的解决方案! 谢谢。

1 个答案:

答案 0 :(得分:1)

首先让我说我认为这不是一个好主意。麻烦多于其价值。但是这里:

prefix operator |
postfix operator |

prefix func | <T: Comparable & SignedNumeric>(f: () -> T) -> T {
    return f()
}

postfix func | <T: Comparable & SignedNumeric>(n: T) -> () -> T {
    return { abs(n) }
}


|42| // returns 42
|(-42)| // returns 42

这个想法是,后缀运算符返回一个函数,该函数随后用作前缀运算符的参数,然后该函数返回最终结果。我本来是用另一种方法(前缀运算符返回函数),但是编译器不喜欢这样-似乎后缀运算符具有更高的优先级。

返回函数的优点是|42不编译(因为参数类型不匹配),并且在42|编译时,使用它会立即出错在计算中由于类型不匹配而造成的。

如果将其与文字一起使用,则仍必须用括号括起负数,因为Swift无法解析两个连续的前缀运算符。我还没有对此进行太多测试,可能还有其他一些无法编译的极端情况。