Max
Max

Reputation: 22315

Underscore treats val like a def

I think I understand why this happens

def x() = 1
x _   // () => Int
x() _ // error: _ must follow method; cannot follow Int

x _ turns the method into a function, so you get a no-arg function. x() _ makes no sense because calling the method gives you an Int, which can't be turned into a function. But then why does this happen?

val x = 1
x _   // () => Int

Upvotes: 1

Views: 57

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

There is little difference between a val and a parameterless method, except that the parameterless method doesn't calculate the value until it's called (and will re-calculate the value for each additional call). What really happens to a val underneath is that there is a private field declared along with a public accessor method that returns that value.

object Test {
    def method = 1
    val value = 1
}

Compiles to:

object Test extends Object {
  def method(): Int = 1;
  private[this] val value: Int = _;
  <stable> <accessor> def value(): Int = Test.this.value;
  def <init>(): Test.type = {
    Test.super.<init>();
    Test.this.value = 1;
    ()
  }
}

Note the line:

 <stable> <accessor> def value(): Int = Test.this.value;

This allows you to, for example, override a def in a super-class with a val in a sub-class, since it's actually overriding a method. Since a method is actually generated, you are allowed to eta-expand a val into a function.

Upvotes: 3

Related Questions