首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala的"postfix ops“

Scala的"postfix ops“
EN

Stack Overflow用户
提问于 2012-10-22 20:11:23
回答 3查看 34.9K关注 0票数 62

我已经找了半个小时了,还是找不到。

SIP: Modularizing Language Features中,有许多特性需要在Scala2.10 (import language.feature)中显式“启用”。其中有postfixOps,我在任何地方都找不到对它的引用。这个特性到底允许什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-22 20:17:09

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

代码语言:javascript
复制
List(1,2,3) tail

而不是

代码语言:javascript
复制
List(1,2,3).tail

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

代码语言:javascript
复制
val appender:List[Int] => List[Int] = List(1,2,3) ::: //add ; here
List(3,4,5).foreach {println}

并且错误消息没有多大帮助:

代码语言:javascript
复制
    value ::: is not a member of Unit

它尝试对foreach调用的结果调用:::方法,该方法的类型为Unit。这可能不是程序员的本意。要获得正确的结果,您需要在第一行之后插入分号。

票数 63
EN

Stack Overflow用户

发布于 2014-06-26 02:57:43

有史以来最简单的答案:

从不带参数的方法中删除点是DEPRECATED

代码语言:javascript
复制
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,这样做是安全的!还有像zip这样的purely functional方法。

代码语言:javascript
复制
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)

长篇大论:为什么选择

代码语言:javascript
复制
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)后缀运算符-实际上是一个不带参数的方法调用(a!==a.!)而且没有括号。(被认为不安全,已弃用)

代码语言:javascript
复制
val b1 = MyBool(false) !!!
List(1,2,3) head

2)后缀运算符是方法,应该结束一行,否则将被视为中缀。

代码语言:javascript
复制
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方法

代码语言:javascript
复制
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作为参数的方法执行此操作!

代码语言:javascript
复制
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可见来启用后缀运算符tail。这可以通过添加import子句'import scala.language.postfixOps‘或通过设置编译器选项-language:postfixOps来实现。有关为什么应该显式启用该特性的讨论,请参阅Scala文档中的值scala.language.postfixOps。

票数 36
EN

Stack Overflow用户

发布于 2012-10-22 20:16:47

它指的是调用nullary (没有arg list或空arg list)方法作为后缀运算符的能力:

举个例子:

代码语言:javascript
复制
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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13011204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档