Fel*_*lix 15 dictionary functional-programming scala infix-notation parentheses
在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)_
Run Code Online (Sandbox Code Playgroud)
(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
Run Code Online (Sandbox Code Playgroud)
mkString显然返回一个字符串,在其上(通过隐式转换AFAIK)我可以使用map函数.
为什么这个特殊情况需要括号?关于何时以及为何需要它,是否有一般指导原则?
huy*_*hjl 35
这是我在阅读规范后为自己整理的内容:
a.m(b)可以编写a m b.a.m可以编写a m.例如a.##(b)可以写a ## b,a.!可以写a!
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.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
Run Code Online (Sandbox Code Playgroud)
有时通过在正确的位置添加点,您可以获得所需的优先级,例如 fromFile(file).mkString map { }
所有优先事项都是在打字和其他阶段之前发生的,所以即使list mkString map function没有意义list.mkString(map).function,这也就是解析它的方式.
在斯卡拉参考提到(6.12.3:???前X中,x和邮政X操作)
在一系列连续类型的inx操作中
t0 op1 t1 op2 . . .opn tn,所有运算符op1, . . . , opn必须具有相同的关联性。
如果它们都是左关联的,则序列解释为(. . . (t0 op1 t1) op2 . . .) opn tn。
在您的情况下,“ map”不是运算符“ mkstring” 的术语,因此您需要分组(括号中用“ fromFile(file) mkString” 括起来)
实际上,Matt R评论:
这并不是一个真正的关联性问题,更多的是,“ Post?x运算符的优先级总是比in?x运算符的优先级低。例如,Eg
e1 op1 e2 op2始终等于(e1 op1 e2) op2”。(也来自6.12.3)
huynhjl的答案(被提议)提供了更多细节,Mark Bush的答案(也被提议)指向“ Scala之路:运算符 ”以说明“任何采用单个参数的方法都可以用作中缀运算符” 。
| 归档时间: |
|
| 查看次数: |
3882 次 |
| 最近记录: |