【问题标题】:scala () vs {} definition of parameter invocation [duplicate]scala()与{}参数调用的定义[重复]
【发布时间】:2017-08-13 21:26:46
【问题描述】:

在 Coursera 课程“Scala 中的函数式编程原理”第 1 周示例作业 (https://www.coursera.org/learn/progfun1/programming/xIz9O/example-assignment) 中,Martin Ordersky 在他的一个 cmets 中提到(在 ListsSuites.scala 测试的第 44 行)

   * In Scala, it is allowed to pass an argument to a method using the block
   * syntax, i.e. `{ argument }` instead of parentheses `(argument)`.

所以在 Scala 中分配函数定义时是否相当于说:

def foo = ()

和

def foo = {}

【问题讨论】:

    标签: scala scalatest


    【解决方案1】:

    这是定义一个方法/定义 - 调用定义时引用的注释

    scala> def foo(arg1: Int) = arg1 + 1
    foo: foo[](val arg1: Int) => Int
    
    scala> foo(1) // round parenthesis
    res0: Int = 2
    
    scala> foo{1} // bracket parenthesis
    res1: Int = 2
    

    另请注意,def 的主体不需要括在括号中。因此,使用您的示例,以下所有内容都是等效的:

    def foo = (???) // ??? means implementation not yet defined
    def foo = {???}
    def foo = ???
    

    【讨论】:

      【解决方案2】:

      {} 或 ({}) 指代代码块。

      {
        statement1
        statement2
        statement3
      }
      

      最后一条语句将被返回。

      scala> val x = { 
           |  val x = 4 
           |  x + 1
           | }
      x: Int = 5
      

      而() 用于单行表达式。

      什么时候 {} 和 () 可以互换

      1.使用一个参数调用方法

      scala> def printlnme(x: String) = { println(x)}
      printlnme: (x: String)Unit
      
      scala> printlnme("using parenthesis")
      using parenthesis
      
      scala> printlnme{"using braces"}
      using braces
      

      不使用具有多个参数的方法,

      scala> def add(x: Int, y: Int) = { x + y }
      add: (x: Int, y: Int)Int
      
      //can also be (x + y) because one line expression
      //scala> def add(x: Int, y: Int) = ( x + y )
      //add: (x: Int, y: Int)Int
      
      scala> add(1, 2)
      res3: Int = 3
      
      scala> add{1, 2}
      <console>:1: error: ';' expected but ',' found.
      foo{1, 2}
           ^
      

      2.一行表达式

      在这个例子中,我只打印输入。

      scala> List(1, 2, 3).foreach { x => println(x) }
      1
      2
      3
      
      scala> List(1, 2, 3).foreach ( x => println(x) )
      1
      2
      3
      

      或者,说一行map函数。

      scala> List(1, 2, 3) map { _ * 3}
      res11: List[Int] = List(3, 6, 9)
      
      scala> List(1, 2, 3) map ( _ * 3 )
      res12: List[Int] = List(3, 6, 9)
      

      但是()单独不能和多行语句一起使用

      scala> :paste
      
      List(1, 2, 3) foreach ( x =>
           val y = x * 28
           println(y)
      )
      
      <console>:2: error: illegal start of simple expression
           val y = x * 28
           ^
      

      您仍然需要({}) 才能对多行使用括号。

      scala> :paste
      
      List(1, 2, 3) foreach ( x => {
           val y = x * 28
           println(y)
      })
      
      28
      56
      84
      

      【讨论】:

        【解决方案3】:

        特别是在您的情况下:是的,它们都会导致foo: Unit

        在许多情况下,由于都对表达式求值,它们会产生相同的效果,但严格来说它们是不同的。 {} 是一个空块,计算结果为 Unit,因为它(不存在)最后一条语句计算结果为 Unit,而 () 是 Unit 类型的默认值。

        long ago 提出了这个问题,并且 imo 关于您的特定问题的关键点是,您不能将 {} 语法与需要超过 1 个参数(非柯里化)的函数一起使用。其他案例的广泛报道可以找到here。一般来说,这两者是不同的;他们只是经常碰巧做同样的事情。

        【讨论】:

          【解决方案4】:

          为了给你简单的回答,两者都是内存块的表示,但在块可以容纳多少方面有所不同。

          {} 用于多行定义

           Seq(1, 2, 3, 4, 5).map { x =>
                x + 1
                x - 1
              }
          

          () 用于单行定义

             Seq(1, 2, 3, 4, 5).map(x =>
                x + 1
                x -1)
          

          上面的代码会给你编译器错误,因为它只能容纳一行。但你也可以使用 {} inside () 来容纳多行跟随

          Seq(1, 2, 3, 4, 5).map(x => {
            x + 1
            x - 1
          })
          

          【讨论】:

            猜你喜欢
            • 2014-08-18
            • 1970-01-01
            • 2015-08-27
            • 1970-01-01
            • 1970-01-01
            • 2021-01-30
            • 2012-10-18
            • 1970-01-01
            • 2014-07-07
            相关资源
            最近更新 更多