我已经搜索了半个小时,仍然无法弄明白。
在SIP: Modularizing Language Features中,有许多功能需要在Scala 2.10(import language.feature
)中明确“启用”。
其中有postfixOps
,我无法在任何地方找到参考。这个功能究竟允许什么?
答案 0 :(得分:58)
它允许您在后缀位置使用运算符语法。例如
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
方法,该调用的类型为Unit
。这可能不是程序员的意图。要获得正确的结果,您需要在第一行之后插入分号。
答案 1 :(得分:30)
有史以来最简单的答案:
从没有参数的方法中删除点是DEPRECATED!
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)
确定在带有higher order function的一个参数的方法中删除点,例如map,filter,count并且安全! 此外,还有purely functional方法,例如zip。
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)中缀运算符是带有一个参数的方法,可以在没有点和圆括号的情况下调用。仅适用于purely functional方法
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) 但是,您应该仅对使用higher order function作为参数的方法执行此操作!
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重新运行 有关详细警告:应该通过make启用postfix operator tail 隐含值scala.language.postfixOps可见。这可以 通过添加import子句'import来实现 scala.language.postfixOps'或通过设置编译器选项 -language:postfixOps。有关该功能的讨论原因,请参阅Scala文档以获取值scala.language.postfixOps 明确启用。
答案 2 :(得分:5)
它指的是调用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