何时在 Scala 中缀表示法中使用括号 [英] When to use parenthesis in Scala infix notation

查看:38
本文介绍了何时在 Scala 中缀表示法中使用括号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 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 written a m b.
  • Any method which does not require a parameter can be used as a postfix operator: a.m can be written a m.

比如a.##(b)可以写成a ## ba.!可以写成一个!

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)).bamfoo bar baz bam bim 表示 (foo.bar(baz)).bam(bim).
  • 还给出了对象a的无参数方法mamm是有效的,但amm不是这样将解析为 exp1 op exp2.
  • Postfix operators have lower precedence than infix operators, so foo bar baz means foo.bar(baz) while foo bar baz bam means (foo.bar(baz)).bam and foo bar baz bam bim means (foo.bar(baz)).bam(bim).
  • Also given a parameterless method m of object a, a.m.m is valid but a m m is not as it would parse as exp1 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 functionlist.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆