何时在 Scala 中缀表示法中使用括号 [英] When to use parenthesis in Scala infix notation
问题描述
在 Scala 中编程时,我会做越来越多的函数式工作.然而,当使用中缀表示法时,很难分辨什么时候需要括号,什么时候不需要.
When programming in Scala, I do more and more functional stuff. However, when using infix notation it is hard to tell when you need parenthesis and when you don't.
例如下面一段代码:
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) 需要括号才能编译.删除后,我收到以下错误:
The (fromFile(file) mkString) needs parenthesis in order to compile. When removed I get the following error:
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 函数.
mkString obviously returns a string on which (by implicit conversion AFAIK)I can use the map function.
为什么这个特殊情况需要括号?是否有关于何时以及为何需要它的一般指南?
Why does this particular case needs parentheses? Is there a general guideline on when and why you need it?
推荐答案
这是我在阅读规范后为自己整理的:
This is what I put together for myself after reading the spec:
- 任何接受单个参数的方法都可以用作中缀运算符:
a.m(b)
可以写成a m b
. - 任何不需要参数的方法都可以用作后缀运算符:
a.m
可以写成a m
.
- Any method which takes a single parameter can be used as an infix operator:
a.m(b)
can be writtena m b
. - Any method which does not require a parameter can be used as a postfix operator:
a.m
can be writtena m
.
比如a.##(b)
可以写成a ## b
,a.!
可以写成一个!
For instance a.##(b)
can be written a ## b
and a.!
can be written a!
- 后缀运算符的优先级低于中缀运算符,所以
foo bar baz
的意思是foo.bar(baz)
而foo barbaz bam
表示(foo.bar(baz)).bam
和foo bar baz bam bim
表示(foo.bar(baz)).bam(bim)
. - 还给出了对象a的无参数方法m,
amm
是有效的,但amm
不是这样将解析为exp1 op exp2
.
- Postfix operators have lower precedence than infix operators, so
foo bar baz
meansfoo.bar(baz)
whilefoo bar baz bam
means(foo.bar(baz)).bam
andfoo bar baz bam bim
means(foo.bar(baz)).bam(bim)
. - Also given a parameterless method m of object a,
a.m.m
is valid buta m m
is not as it would parse asexp1 op exp2
.
因为有一个 mkString
版本接受单个参数,所以它会被视为 fromFile(file) mkString map caesar(k)_
中的中缀运算符.还有一个版本的 mkString
不带参数,可以用作后缀运算符:
Because there is a version of mkString
that takes a single parameter it will be seen as an infix opertor in fromFile(file) mkString map caesar(k)_
. There is also a version of mkString
that takes no parameter which can be used a as postfix operator:
scala> List(1,2) mkString
res1: String = 12
scala> List(1,2) mkString "a"
res2: String = 1a2
有时通过在正确的位置添加点,您可以获得所需的优先级,例如fromFile(file).mkString map { }
Sometime by adding dot in the right location, you can get the precedence you need, e.g. fromFile(file).mkString map { }
所有这些优先事项都发生在输入和其他阶段之前,所以即使 list mkString map function
与 list.mkString(map).function
一样没有意义,这个是它的解析方式.
And all that precedence thing happens before typing and other phases, so even though list mkString map function
makes no sense as list.mkString(map).function
, this is how it will be parsed.
这篇关于何时在 Scala 中缀表示法中使用括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!