Scala 中置, 前置, 后置操作符

拟此篇以温习 Scala 对方法调用上的一些约定. 标题中说是关于操作符的事, 其实 Scala 像有了访问方法和属性的一致性原则一样, 可以说操作符与方法更是统一的, 或者说只有方法调用. 此处所称的操作符只不过是 Scala 对无参(prrameterless), 或只有一个参数的方法, 和特殊的四个 unary_+, unary_-, unary_!, unary_~ 方法的便捷的调用约定格式.

一. 中置操作符(对只有一个参数方法的调用约定, a plus b)

case class MyNumber(value: Int) {
  def +(that: MyNumber) = MyNumber(this.value + that.value)
}

调用方式

第一行是用点语法的标准方法调用格式, Scala 在当方法只有一个参数时, 可以省略点, 以及括号, 因此可写为上面第二行种的格式. 所以方法 + 就化身为了中置操作符了.

+ 只是一个普通的方法名而已, 因为 Scala 可以用很多符号来定义方法. 所以对于任何的只有一个参数的方法调用可以这么写, 假如 MyNumber 定义了方法

应用同样的规则可写成

这个约定十分有利于写出 DSL 风格的代码, 例如我们在测试中用 MustMatchers 时这么断言

上面其实就是进行连续了三次是置操作符调用 size, have, 和 must.

除中置操作符外, 另外两种前置与后置操作符又统称为一元操作符, 因为它是不带参数的, 首先来看后置操作符

二. 后置操作符(对于无参数的方法的调用约定, a next)

当函数无参数时, 调用时规则约定其实和只有一个参数时是一样的, 省略点以及括号, 既然一个参数都没有, 所以就只有方法名了. 例子

调用方式

由于前面定义的 -- 是无参方法(Parameterless), 所以调用时不能加括号, MyNumber(10).--() 是错误的. 如果是定义的空参数方法(Empty-Paren), 则既可以 MyNumber(10).--() 也可以写成 MyNumber(10) --, 还能 MyNumber(10).--, 但后两者会有警告.

所以对于后置操作符, 特别是无副作用时应该定义为不带括号的无参方法, 形如  def -- = ....

后置的调用方式很常见, 如

三. 前置操作符(+, -, !, ~ 的几个特例方法而已)

Scala 可以实现在操作数前加  +, -, !, ~ 操作符, 如 -a, 所以它们叫做前置(prefix) 操作符. Scala 的做法是把它们分别映射到方法 unary_+, unary_-, unary_!, 和 unary_~. 示例

调用时写成

注意, 前置操作只能映射前面四种操作, 想别的都没有. 比如你是否有冲动在 Scala 中实现出  ++a 呢? Scala 是不支持传统的 ++ 递增操作, 后置的 a++ 我们可以用 def ++ = ... 实现. 对于前置的 ++a 如果尝试写成


下面是测试上面三种方式的完整代码

上面代码的输出

Infix: MyNumber(30)
MyNumber(30)
Postfix1: MyNumber(11)
MyNumber(11)
Postfix2: MyNumber(9)
MyNumber(9)
MyNumber(9)
Prefix: MyNumber(-10)
MyNumber(-10)
MyNumber(-10)

本文链接 https://yanbin.blog/scala-infix-prefix-postfix-operators/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments