Scala anonymous function syntax and return type

2019-04-11 04:35发布

问题:

I have found few kinds of anonymous function syntax in scala:

val m5_1 = { (n: Int) => n * 5 }

val m5_2 = (n: Int) => { n * 5 } : Int

val m5_3: Int => Int = n => { n * 5 }

Is that all types or some more syntax kinds present?

Are they all equivalent?

Which one is more/less preferred?

How can I specify the return type in m5_1 ?

回答1:

I'll try to add to @pamu's answer:

Which one is more/less preferred?

I'd say the second variant is a bit uncommon. When the type inference is easily visible, you can go for the first, otherwise being explicit as in the third case is good. You don't need braces there, so a simpler variant is

val m5_3: Int => Int = n => n * 5

Or even

val m5_3: Int => Int = _ * 5

How can I specify the return type in m5_1 ?

The return type is Int => Int, so that is the same type annotation as you use in the third case:

val m5_1: Int => Int = { (n: Int) => n * 5 }

But then of course, you can let Scala use the type inference on the right hand side:

val m5_1: Int => Int = n => n * 5

And therefore this is identical to your third form.

Note that the : Int in the second form is not defining the type of m5_2, which is Int => Int and not Int. It simply tells Scala that the type of n * 5 is meant to be Int. This can aid you reading the code, but it doesn't actually change the way the type is inferred in this case. You can think of your second form of actually being:

val m5_2 = (n: Int) => { 
  val res = n * 5: Int  // : Int redundant here because it is already inferred
  res
}

Where val res = n * 5: Int has the same effect as val res: Int = n * 5



回答2:

Is that all types or some more syntax kinds present ?

Lambda syntax requires the input parameter type to be known. If not compiler throws an error. In all the syntaxes you are trying to give this information. But return type can be inferred by the compiler.

Are they all equivalent?

All are equivalent

Which one is more/less preferred ?

The below one is recommended if you do not want to see explicit type annotation

val m5_1 = { (n: Int) => n * 5 }

How can I specify the return type in m5_1 ?

Return type is inferred from the last line of the lambda. The last line is n * 5 which of type Int. So, compiler infers the type for you. You can skip giving the type information explicitly



回答3:

Well, the above answers have properly explained almost everything I guess. I just want to add one more variant that we could do here:

val m5_4 = {n=> n*5}:Int=>Int