【问题标题】:Access field from trait in companion object从伴随对象中的特征访问字段
【发布时间】:2016-10-29 15:10:34
【问题描述】:

我有类似下面的代码(我简化了它):

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)))
}

基本上,我在特征A 中声明了一个常量CONST_VALUE。我正在尝试在伴随对象B 中使用它来实例化类B。但是,我无法从伴随对象 B 访问 A.CONST_VALUE。(我遇到编译错误)。

那我该怎么做呢?

【问题讨论】:

  • 旁注 - 为了使变量成为常量,您需要添加 final 关键字:final val CONST_VALUE = 10

标签: scala


【解决方案1】:

你不能这样做。

首先,object Bclass B 的伴随对象,而不是 trait A。 Companions 需要具有相同的名称并在相同的编译单元中定义。

其次,CONST_VALUEtrait A 的实例字段。它是A实例 的成员,而不是A 的成员。

第三,当你说A.CONST_VALUE 时,你基本上是在A 上调用CONST_VALUE 方法。但是你只能调用对象/值的方法。 A 不是对象,它是一个类型,类型和值存在于不同的世界中,你不能将两者混为一谈。

第四,您的CONSTANT_VALUE 被误导了:只有final vals 是常量值定义,所以您的CONSTANT_VALUE 实际上不是常量值。

第五,您的apply 方法调用自己(B()B.apply() 的语法糖),因此需要返回类型注释。

第六,您的apply 方法使用两个 参数调用自身,但它仅使用一个 参数定义。

第七,你创建了一个Array[Array[Byte]],但我不清楚你为什么要这样做以及你需要它做什么。

这是一整套卡车的问题(特别是考虑到只有几行代码开始),您需要一个一个地解决这些问题。这是一种可能的部分解决方案,但我不清楚究竟您要达到什么目的。

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)))
}

【讨论】:

    【解决方案2】:

    在伴随对象 A 中声明 val CONST_VALUE = 10 而不是 trait A。还更正了对象B中的apply方法定义

    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)))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-22
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多