问题
I know that if we want to pass a block of code in curly braces as an argument to functions defined using def
, we can write:
def run(func: => Unit) {
func
}
run {
print(1)
println(2)
} // prints 12
But is there a way to achieve the same style with an anonymous function? I have tried the following:
val v: (()=>Unit) => Unit = ( w: ()=> Unit) => { w() }
v( () => { println(1); println(2) } ) // Works as expected. Prints 12
v { println(1); println(2) } // error: type mismatch
Correction:
()=>Unit
doesn't translate to a function that has a by-name parameter which would allow it to accept code enclosed by curly braces as a parameter. So my question's second part was incorrect.
Alexey Romanov's answer works perfectly if we don't re-specify the argument type in function literal, but if we re-specify the argument type in the function literal which matches the type of variable exactly, it is seen as an error. For example, if we write
val v: (=>Unit) => Unit = (w) => { println(0); w } // works
val v: (=>Unit) => Unit = (w:=>Unit) => { println(0); w } // error
val v: (Int => Int) = (w) => 43 // works
val v: (Int => Int) = (w:Int) => 43 // works as well
回答1:
val v: (=>Unit) => Unit = w => { println(0); w }
v { println(1); println(2) }
println(0)
inserted purely so you can see this is really a by-name parameter: 0
is printed before 1
and 2
.
回答2:
The pattern block :=> Type
is called by-name
parameter and does not have to be a function but can be any block of code that evaluated to the type Type
. That's why the first example works.
The second part does not work because the passed argument:
println(1); println(2)
evaluates to Unit
and does not match the expected type ()=>Unit
.
来源:https://stackoverflow.com/questions/56866965/is-there-a-way-to-call-a-function-defined-using-val-in-scala-with-the-whole-cu