Overriding Companion and Scala MatchError Object Values

Can someone clarify why the following code raises MatchError? What is the meaning of MatchError in this case?

class A {
  def g = A.f
}

object A {
  val f = "Object A"
}


class B extends A {
  override val A.f = "Object B"
}

val b = new B
b.g

Given that this does not work, is there a way to override the companion object val or def like this?

+5
source share
2 answers

First, why do you see MatchError. The value for the object (Af) is considered a stable identifier (as stated in Scala), "Stable members are [...] members introduced by object definitions or definitions of non-volatile type values").

Here's what the look looks like:

object A extends scala.AnyRef {
    ...
    private[this] val f: String = "Object A";
    <stable> <accessor> def f: String = A.this.f
}

"desugars" ( ) :

<synthetic> private[this] val x$1: Unit = ("Object B": String("Object B") @unchecked) match {
    case A.f => ()
}

"Object B" "Object A", MatchError.

: / . , ​​ . , , vals/defs -.

+3

! scalac -print test.scala, - ,

[[syntax trees at end of                   cleanup]] // scala
package <empty> {
  class A extends Object {
    def g(): String = A.f();
    def <init>(): A = {
      A.super.<init>();
      ()
    }
  };
  object A extends Object {
    private[this] val f: String = _;
    <stable> <accessor> def f(): String = A.this.f;
    def <init>(): A.type = {
      A.super.<init>();
      A.this.f = "Object A";
      ()
    }
  };
  class B extends A {
    <synthetic> private[this] val x$1: runtime.BoxedUnit = _;
    def <init>(): B = {
      B.super.<init>();
      B.this.x$1 = {
        case <synthetic> val x1: String = ("Object B": String("Object B"));
        case5(){
          if (A.f().==(x1))
            {
              val x2: String = x1;
              matchEnd4(scala.runtime.BoxedUnit.UNIT)
            }
          else
            case6()
        };
        case6(){
          matchEnd4(throw new MatchError(x1))
        };
        matchEnd4(x: runtime.BoxedUnit){
          scala.runtime.BoxedUnit.UNIT
        }
      };
      ()
    }
  }
}

, B , , , , val A.f, if (A.f().==(x1)). , ? , , case6(). , class B override val A.f = "Object A".

class B extends A {
        override val A.f = "Object A"
}

scala> val b = new B
b: B = B@1fc6dc6

, ? ,

class B extends A {
        override def g = "Object B"
}
scala> val b = new B
b: B = B@19bdb65

scala> b.g
res1: String = Object B

class B extends A {
        val f = "Object B"
}
scala> val b = new B
b: B = B@1e5ed7b

scala> b.f
res0: String = Object B
+1

All Articles