用于从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。叫。)
答案 0 :(得分:4)
如果对象的被调用函数中没有参数,则使用空格而不是点称为后缀表示法;如果存在函数的参数,则使用中缀表示法需要。
Postix示例:l sum
,相当于l.sum
中缀示例:l map (_ * 2)
,相当于l.map(_ * 2)
这些符号的问题在于它们的解释本质上更加含糊不清。数学的经典例子:
因此,它不是一个不同的运算符,但与点相同,只是容易出现歧义,可能会导致像你的情况一样的语法错误,或者当你链接中缀运算符时更糟糕的逻辑错误。
你可以用这种方式用中缀表示法表达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
,那么空格就不必传达长度纯净的想法。