What is the formal difference in Scala between braces and parentheses, and when should they be used?

后端 未结 9 1316
萌比男神i
萌比男神i 2020-11-22 07:09

What is the formal difference between passing arguments to functions in parentheses () and in braces {}?

The feeling I got from the Pro

9条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-22 08:00

    I think it is worth explaining their usage in function calls and why various things happen. As someone already said curly braces define a block of code, which is also an expression so can be put where expression is expected and it will be evaluated. When evaluated, its statements are executed and last's statement value is the result of whole block evaluation (somewhat like in Ruby).

    Having that we can do things like:

    2 + { 3 }             // res: Int = 5
    val x = { 4 }         // res: x: Int = 4
    List({1},{2},{3})     // res: List[Int] = List(1,2,3)
    

    Last example is just a function call with three parameters, of which each is evaluated first.

    Now to see how it works with function calls let's define simple function that take another function as a parameter.

    def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
    

    To call it, we need to pass function that takes one param of type Int, so we can use function literal and pass it to foo:

    foo( x => println(x) )
    

    Now as said before we can use block of code in place of an expression so let's use it

    foo({ x => println(x) })
    

    What happens here is that code inside {} is evaluated, and the function value is returned as a value of the block evaluation, this value is then passed to foo. This is semantically the same as previous call.

    But we can add something more:

    foo({ println("Hey"); x => println(x) })
    

    Now our code block contains two statements, and because it is evaluated before foo is executed, what happens is that first "Hey" is printed, then our function is passed to foo, "Entering foo" is printed and lastly "4" is printed.

    This looks a bit ugly though and Scala lets us to skip the parenthesis in this case, so we can write:

    foo { println("Hey"); x => println(x) }
    

    or

    foo { x => println(x) }
    

    That looks much nicer and is equivalent to the former ones. Here still block of code is evaluated first and the result of evaluation (which is x => println(x)) is passed as an argument to foo.

提交回复
热议问题