在Scala中编程时,我会做越来越多的功能性工作。但是,在使用中缀表示法时,很难说出何时需要括号,什么时候不需要括号。
例如下面的代码:
def caesar(k:Int)(c:Char) = c match {
case c if c isLower => ('a'+((c-'a'+k)%26)).toChar
case c if c isUpper => ('A'+((c-'A'+k)%26)).toChar
case _ => c
}
def encrypt(file:String,k:Int) = (fromFile(file) mkString) map caesar(k)_
(fromFile(file)mkString)需要括号才能进行编译。删除后,出现以下错误:
Caesar.scala:24: error: not found: value map
def encrypt(file:String,k:Int) = fromFile(file) mkString map caesar(k)_
^
one error found
mkString很明显会返回一个字符串,在该字符串上(通过隐式转换AFAIK)我可以使用map函数。
为什么这个特殊情况需要括号?是否有关于何时何地需要它的通用指南?
最佳答案
这是我在阅读规格后为自己准备的:
任何采用单个参数的方法都可以用作中缀运算符:a.m(b)
可以写为a m b
。
不需要参数的任何方法都可以用作后缀运算符:a.m
可以写为a m
。
例如,a.##(b)
可以写为a ## b
,而a.!
可以写为a!
Postfix运算符的优先级低于infix运算符,因此foo bar baz
表示foo.bar(baz)
,而foo bar baz bam
表示(foo.bar(baz)).bam
和foo bar baz bam bim
表示(foo.bar(baz)).bam(bim)
。
同样给定对象a的无参数方法m,a.m.m
是有效的,但a m m
无效,因为它将解析为exp1 op exp2
。
因为mkString
有一个采用单个参数的版本,所以它将被视为fromFile(file) mkString map caesar(k)_
中的中缀运算符。 mkString
还有一个不带参数的版本,可用作后缀运算符:
scala> List(1,2) mkString
res1: String = 12
scala> List(1,2) mkString "a"
res2: String = 1a2
有时,在正确的位置添加点,即可获得所需的优先级,例如
fromFile(file).mkString map { }
而且所有这些优先事项都在输入和其他阶段之前发生,因此即使
list mkString map function
与list.mkString(map).function
没有任何意义,也仍将以这种方式进行解析。关于scala - 何时在Scala缀表示法中使用括号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5592642/