问题描述
在scala中进行编程时,我做的功能越来越多。但是,当使用中缀符号时,很难判断何时需要括号,何时不需要。例如下面的代码片段:
def caesar(k:Int)(c:Char)= c match {
(fromFile(file)mkString)需要括号才能进行编译。删除后,我收到以下错误:
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)_
Caesar.scala:24:error:not found:value map
def加密(file:String,k:Int)= fromFile(file)mkString map caesar(k)_
^
发现一个错误
mkString显然返回一个字符串(通过隐式转换AFAIK)我可以使用地图函数。
为什么这个特殊情况需要括号吗?有没有一个关于什么时候和为什么需要它的一般准则?
解决方案这是我阅读规格后自己放在一起的:
- 任何采用单个参数的方法都可以用作中缀运算符:
am(b) code>可以写成
amb
。 - 任何不需要参数的方法都可以用作后缀运算符:
am
可以写成am
。
例如 a。##(b)
可以写成 a ## b
和 a。!
可以写成 a!
- Postfix操作符的优先级低于中缀运算符,因此
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 ,
amm
有效但amm
不像解析为exp1 op exp2
。
因为有一个版本的 mkString
需要一个参数,它将被视为<$ c中的中缀操作符$ c> fromFile(file)mkString map caesar(k)_ 。还有一个版本的 mkString
,它不会使用可用作postfix操作符的参数:
阶>列表(1,2)mkString
res1:String = 12
scala>列表(1,2)mkStringa
res2:String = 1a2
有时由在正确的位置添加点,您可以获得所需的优先级,例如 fromFile(file).mkString map {}
所有优先事项在打字和其他阶段之前发生,所以即使 list mkString map function
没有意义,因为 list.mkString(map).function
,这是怎么回事被解析。
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.
For example the following piece of code:
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)_
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 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:
- 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
.
For instance a.##(b)
can be written a ## b
and a.!
can be written a!
- 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
.
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
Sometime by adding dot in the right location, you can get the precedence you need, e.g. fromFile(file).mkString map { }
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中缀符号中使用括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!