Jack
Jack

Reputation: 5880

what's the difference between def and var/val for an anonymous function

I'm confused about anonymous function definitions as following:

var plusOne = (x:Int)=>x+1
// or val plusOne=(x:Int)=>x+1
println(plusOne(2))

Or

def plusOne = (x:Int)=>x+1
println(plusOne(2))

What's the difference please in var/val and def for a function name.

Upvotes: 0

Views: 767

Answers (4)

sxiang3
sxiang3

Reputation: 1

It might be clear from the Class File Disassembler results using javap. Save the following code as Test.scala

class Test {
  val fVal: Int => Int = x => x + 1
  var fVar: Int => Int = x => x + 1
  def fDef(x: Int): Int = { x + 1 }
}

and do scalac Test.scala; javap Test will show

Compiled from "Test.scala"
public class Test {
  public scala.Function1<java.lang.Object, java.lang.Object> fVal();
  public scala.Function1<java.lang.Object, java.lang.Object> fVar();
  public void fVar_$eq(scala.Function1<java.lang.Object, java.lang.Object>);
  public int fDef(int);
  public Test();
}

As is shown in the results above, val and fVar are represented as methods that return a Function1 object. The difference is fVar has an additional "setter". While fDef is like normal Java method.

Upvotes: 0

elm
elm

Reputation: 20415

Note also with val (or var) one instance of the function is created and is used for any number of invocations to that function, whereas with def a new instance of the function is created for each invocation. Yet, for

def f (i:Int) = i+1
f: (i: Int)Int

note

val g = f _
g: Int => Int = <function1>

Upvotes: 1

Pranav Shukla
Pranav Shukla

Reputation: 2226

  • val declares an "immutable variable or rather symbol" that doesn't allow reassignment, right hand side of the assignment is evaluated immediately
  • var declares a "mutable variable" that allows reassignments later to the symbol, right hand side of the assignment is evaluated immediately just like val
  • def declares an "immutable symbol" that doesn't allow reassignment, right hand side is evaluated lazily, i.e. whenever that symbol is referenced later in the code

Example -

var plusOneVar = (x:Int)=>x+1
val plusOneVal = (x:Int)=>x+1
def plusOneDef = (x:Int)=>x+1

plusOneVar = (x:Int)=>x+2 // Reassignment to var is valid
plusOneVal = (x:Int)=>x+2 // Compile time error, reassignment to val
plusOneDef = (x:Int)=>x+2 // Compile time error, reassignment to val

Because you are looking at an example with functions, it is hard to understand. Let's try to understand it with simple variables.

var symbolVar = 100        // line 1
val symbolVal = symbolVar  // line 2
def symbolDef = symbolVar  // line 3

println(symbolVar)  // prints 100
println(symbolVal)  // prints 100
println(symbolDef)  // prints 100 - no surprise yet

symbolVar = symbolVar + 1

println(symbolVal)  // still prints 100 which was evaluated and assigned on line 2
println(symbolDef)  // prints 101 as symbolDef is a def and it depends on symbolVar, line 3 is evaluated again

Upvotes: 8

j will
j will

Reputation: 3807

var plusOne can be reassigned. val plusOne cannot be reassigned. Both are evaluated once. def plusOne is evaluated each time it is called

Upvotes: 2

Related Questions