Scala中点和空格的区别

时间:2016-07-03 18:42:33

标签: scala

用于从Scala中的对象调用函数时,.之间的区别究竟是什么?

出于某种原因,我得到了变化,例如:

scala> val l:List[Int] = 1::Nil
l: List[Int] = List(1, 2, 3)

scala> l foldLeft(0)((hd, nxt) => hd + nxt) 
<console>:13: error: Int(1) does not take parameters
       | foldLeft(1)((hd, nxt) => hd + nxt)
                    ^
scala>l.foldLeft(0)((hd, nxt) => hd + nxt)
res2: Int = 2

(虽然我在这,但是那个操作的名称是什么?我一直试图找到.运算符的严格定义,我不知道它是什么&#39 ; s。叫。)

2 个答案:

答案 0 :(得分:4)

如果对象的被调用函数中没有参数,则使用空格而不是点称为后缀表示法;如果存在函数的参数,则使用中缀表示法需要。

Postix示例:l sum,相当于l.sum

中缀示例:l map (_ * 2),相当于l.map(_ * 2)

这些符号的问题在于它们的解释本质上更加含糊不清。数学的经典例子:

  • 1 + 2 * 3 + 4是不明确的,取决于运营商的优先级。
  • 1。+(2。*(3)。+(4)只有一个有意义的解释。

因此,它不是一个不同的运算符,但与点相同,只是容易出现歧义,可能会导致像你的情况一样的语法错误,或者当你链接中缀运算符时更糟糕的逻辑错误。

你可以用这种方式用中缀表示法表达foldLeft:

(l foldLeft 0)((hd, nxt) => hd + nxt) 

甚至

(0 /: l)((hd, nxt) => hd + nxt)

其中/:只是foldLeft的别名,并且使用以冒号(:)结尾的运算符的唯一语义,这些语义被解释为l./:(0)(与通常相反)。

答案 1 :(得分:0)

Desugar it"-Xprint:parser""-Xprint:typer"

示例1 Desugared:

scala> (List(1,2) foldLeft 0)((hd, nxt) => hd + nxt) 
...
List(1, 2).foldLeft(0)(((hd, nxt) => hd.$plus(nxt)))
...
immutable.this.List.apply[Int](1, 2).foldLeft[Int](0)(((hd: Int, nxt: Int) => hd.+(nxt)));

如您所见,(List(1,2) foldLeft 0)在解析器阶段转换为(List(1, 2).foldLeft(0))。这个表达式返回一个curried函数,它接受第二组括号来产生一个结果(记住一个curried函数只是一个接受一个参数的函数,并返回另一个带有少一个参数的函数)。

示例2 Desugared:

scala> List(1,2) foldLeft(0)((hd, nxt) => hd + nxt) 
...
List(1, 2)(foldLeft(0)(((hd, nxt) => hd.$plus(nxt))))
...
<console>:8: error: not found: value foldLeft
          List(1,2) (foldLeft(0)((hd, nxt) => hd + nxt))

括号围绕(foldLeft(0)((hd, nxt) => hd + nxt))

<强>样式:

您应该使用空格分隔方法的方法是1个对象,后跟1个方法,后跟1个括号,这将生成一个新对象,后面可以跟一个新方法。

obj method paramerer // good

obj method1 paramerer1 method2 paramerer2 // good

obj method1 paramerer1 method2 paramerer2 method3 paramerer3 // compiles, but might need to be broken up

您可以使用postfix跟踪一个不带参数的方法,但这并不总是批准的样式,尤其是对于访问者。

foo.length // good

foo length // compiles, but can be confusing.

空格分隔方法通常保留用于纯函数(如map,flatmap,filter)或域特定语言(DSL)。

如果是foo.length()上没有length,那么空格就不必传达长度纯净的想法。