john john - 3 months ago 8
Scala Question

Scala: what's def actually do?

In Scala, def defined a function, But i don't understand the below code.
Ex.

def v = 10


what's v defination? v is a variable or a function or anything else?

Answer

it's a function that always returns 10. in Java, the equivalent would be

public int v() { return 10; }

this might seem pointless, but the difference is real, and sometimes importantly useful. for example, suppose i define a trait like this:

trait Wrench {
  val size = 14 //millimeters, the default, most common size
}

if i need different size wrench, i can refine the trait

val bigWrench = new Wrench {
  override val size = 21
}

but what if I want an adjustable wrench?

// mutable! not thread safe!
class AdjustableWrench extends Wrench {
  var adjustment = 0

  override val size = 14 + (3 * adjustment) // oops!

  def adjust( turns : Int ) : Unit = {
    adjustment += turns
  }
}

this won't work! size will always be 14!

if I had defined my trait originally as

trait Wrench {
  def size = 14 //millimeters, the default, most common size
}

i'd be able to define bigWrench exactly as I did above, because a val can override a def. but now i can write a functional adjustable wrench too:

// mutable! not thread safe!
class AdjustableWrench extends Wrench {
  var adjustment = 0

  override def size = 14 + (3 * adjustment) // this works

  def adjust( turns : Int ) : Unit = {
    adjustment += turns
  }
}

by originally defining size as a def, rather than a val in the base trait, even though it looked dumb, I preserved the flexibility to override with def or val. it's quite common to define a base trait with very simple defaults, but where implementations might want to do something more complicated. so statements like

def v = 10

are not at all rare.

to get your head around the difference a bit more, compare these two:

def vDef = {
  println("vDef")
  10
}

and

val vVal = {
  println("vVal")
  10
}

both vDef and vVal will evaluate to 10 whenever you access them. but each time you access vDef, you will see the side effect, a print out of vDef. no matter how any times you access vVal, you will see vVal printed out just once.

Comments