Search code examples
scaladefault-constructor

Scala compile error: member of method parameter not visible to class method


I am getting a compile error of:

value txn is not a member of Charge
new Charge(this.txn + that.txn)
                           ^

with the following Scala class definition:

class Charge(txn: Double = 0){
  def combine(that:Charge): Charge = 
    new Charge(this.txn + that.txn)
}

Explicitly declaring txn as a val allows it to work:

class Charge(val txn: Double = 0){
  def combine(that:Charge): Charge = 
    new Charge(this.txn + that.txn)
}

I thought val was assumed? Can somebody explain this? Is it a problem with my understanding of the default constructor or the scope of the method?


Solution

  • In scala, you can define classes in two forms, for ex.

    • class Charge(txn: Double) -> In this case scala compiler compiles it to java like below
    public class Charge {
      ....
      public Charge combine(Charge);
      ....
      public Charge(double);
      ....
    }
    

    As you can notice in compiled java code, there is no public accessor for txn Let's look at another variation of Charge class, If you define like this class Charge(val txn: String), it gets compiled to below

    public class Charge {
    
      ...
      public double txn();
      ...  
      public Charge combine(Charge);
      ...
      public Charge(double);
      ...
    }
    

    As you can see, in this case compiler generates public accessor for txn hence you are able to access that.txn when you mark it as val

    • case class Charge(txn: Double): This is data class for which scala generates getters, equals and toString for you. You can compile this class

    • scalac Charge.scala

    • javap -c Charge.class And then see what it generates