斯卡拉的“后缀操作”

我搜查了半小时,仍然无法弄清楚。

在SIP:模块化语言特性中 ,有一些特性需要在Scala 2.10( import language.feature )中明确的“启用”。 其中有postfixOps ,我只是无法find任何地方的参考。 这个function到底是什么意思?

它允许您在后缀位置使用运算符语法。 例如

 List(1,2,3) tail 

而不是

 List(1,2,3).tail 

在这个无害的例子中,这不是一个问题,但它可能导致歧义。 这不会编译:

 val appender:List[Int] => List[Int] = List(1,2,3) ::: //add ; here List(3,4,5).foreach {println} 

而错误信息不是很有帮助:

  value ::: is not a member of Unit 

它试图对foreach调用的结果调用:::方法,它是Unittypes的。 这可能不是程序员的意图。 为了得到正确的结果,你需要在第一行之后插入一个分号。

有史以来最简单的答案:

从不带参数的方法中删除点是已经过时的 !

 List(1,2,3) reverse //is bad style and will lead to unpredicted behaviour List(1,2,3) map(_*2) reverse //bad too, because reverse can take first method call from the next line (details below) 

可以将地图,滤波器,数值等高阶函数的参数中的方法删除掉点! 另外,像zip这样的纯粹的function方法。

 List(1,2,3) map(_*2) filter(_>2) (List(1,2,3) map(_*2)).reverse //safe and good List(1,3,5) zip List(2,4,6) 

长答案为什么

 case class MyBool(x: Boolean) { def !!! = MyBool(!x) //postfix def or(other: MyBool): MyBool = if(x) other else this //infix def justMethod0() = this //method with empty parameters def justMethod2(a: MyBool, b: MyBool) = this //method with two or more override def toString = if(x) "true" else "false" } 

1) Postfix运算符 – 实际上是一个没有参数(a!== a。!)且没有括号的方法调用。 (被认为不安全并被弃用)

 val b1 = MyBool(false) !!! List(1,2,3) head 

2) Postfix操作符是方法,它应该结束行,否则它将被视为中缀。

 val b1 = MyBool(true) no! no! //ERROR //is actually parsed like val b2 = MyBool(true).no!(no!) //(no!) is unknown identifier //as bad as Vector(1,2,3) toList map(_*2) //ERROR 

3)中缀运算符是一个参数的方法,可以不带圆点和圆括号。 只适用于纯function性的方法

 val c1 = MyBool(true) or b1 or MyBool(true) val c2 = MyBool(true).or(b1).or(MyBool(true)) c1 == c2 

4)如果您使用参数调用,则带有一个或多个参数的方法将链接为无圆点。 def a(),def a(x),def a(x,y)但是你只应该使用高阶函数作为参数的方法!

 val d1 = MyBool(true) justMethod2(b1, c1) or b1 justMethod0() justMethod2(c1, b1) //yes, it works, but it may be confusing idea val d2 = MyBool(true).justMethod2(b1,c1).or(b1).justMethod0().justMethod2(c1, b1) d1 == d2 //looks familiar? This is where it should be used: List(1,2,3) filter(_>1) map(_*2) 

示例警告:

警告:有1次贬低警告; 使用-deprecation重新运行警告:通过使隐式值scala.language.postfixOps可见,应启用postfix运算符尾部。 这可以通过添加import子句“import scala.language.postfixOps”或通过设置编译器选项-language:postfixOps来实现。 有关讨论为什么应明确启用该function的讨论,请参阅Scala文档以了解scala.language.postfixOps的值。

它指的是能够调用一个nullary(没有arg列表或空arg列表)方法作为后缀运算符:

举例来说:

 case class MyBool(value: Boolean) { def negated = new MyBool(!value) } val b1 = MyBool( true ) val b2 = b1 negated // Same as b1.negated 

请参阅: http : //www.scala-lang.org/node/118