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

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

问题描述

在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加密(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 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.

      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 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.

      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中缀符号中使用括号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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