在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)).bamfoo 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 functionlist.mkString(map).function没有任何意义,也仍将以这种方式进行解析。

关于scala - 何时在Scala缀表示法中使用括号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5592642/

10-11 10:25