Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access field from trait in companion object

Tags:

scala

I have something like the following code (I simplified it):

trait A {
  val CONST_VALUE = 10
}

class B(someValue: Int, values: Array[Int]) extends A {   
  //some methods
}

object B {
  def apply(someValue: Int) = B(someValue, Array.ofDim[Array[Byte]](someValue).map(block => Array.fill[Byte](A.CONST_VALUE)(0)))
}

Basically, I declared a constant CONST_VALUE in the trait A. I am trying to use it in the companion object B to instantiate the class B. However, I can't access A.CONST_VALUE from the companion object B.(I'm getting a compilation error).

So how could I do this?

like image 967
octavian Avatar asked Sep 06 '25 17:09

octavian


2 Answers

You can't do this.

First of all, object B is the companion object to class B, not to trait A. Companions need to have the same name and be defined in the same compilation unit.

Secondly, CONST_VALUE is an instance field of trait A. It is a member of an instance of A, not a member of A.

Thirdly, when you say A.CONST_VALUE you are basically calling the method CONST_VALUE on A. But you can only call methods on objects/values. A is not an object, it is a type, types and values live in different worlds, you cannot mix the two.

And fourth, your CONSTANT_VALUE is misleadingly named: only final vals are constant value definitions, so your CONSTANT_VALUE is not actually a constant value.

Fifth, your apply method calls itself (B() is syntactic sugar for B.apply()), and thus needs a return type annotation.

Sixth, your apply method calls itself with two arguments, but it is defined with only one parameter.

Seventh, you create an Array[Array[Byte]], but it is not clear to me why you want to do that and what you need it for.

That's a whole truckload of problems (especially considering that there are only a handful of lines of code to begin with), which you need to fix one-by-one. Here's one possible partial solution, but it is not clear to me what it is exactly that you are trying to achieve.

trait A

object A {
  final val CONST_VALUE = 10
}

class B(someValue: Int, values: Array[Int]) extends A {   
  //some methods
}

object B {
  def apply(someValue: Int): B = new B(
    someValue, 
    Array.ofDim[Array[Byte]](someValue).map(block => Array.fill[Byte](A.CONST_VALUE)(0)))
}
like image 133
Jörg W Mittag Avatar answered Sep 09 '25 03:09

Jörg W Mittag


Declare val CONST_VALUE = 10 inside the companion object A instead of trait A. Also corrected the apply method definition in object B

trait A {

}

object A {
  final val CONST_VALUE = 10
}

class B(someValue: Int, values: Array[Int]) extends A {   
  //some methods
}

object B {
  def apply(someValue: Int) = new B(someValue, Array.ofDim[Int](someValue).flatMap(block => Array.fill[Int](A.CONST_VALUE)(0)))
}
like image 36
pamu Avatar answered Sep 09 '25 05:09

pamu