确定Scala中的overriden成员变量的类型

时间:2017-09-29 11:48:29

标签: scala

我有这样的类型层次结构:

trait Description {

}

trait DescriptionProvider {
   val description: Description
}

object Sample extends DescriptionProvider {
  object description extends Description {
    val name = "foo"
  }
}

现在我正在寻找一个函数f,它为a.description的任何子类型提供具体值DescriptionProvider,包括它的类型。

E.g。 f(Sample).name应编译并评估为foo

一种明显的访问方法当然不能正常工作

def obvious[T <: DescriptionProvider](x: T) = x.description obvious(Sample).name // doesn't compile of course, as foo returns only Description.

有没有任何技巧如何设计这样的函数f而不对对象层次结构进行大量更改(已经存在并且巨大)?

我已经尝试过以某种方式工作的宏,但是IntelliJ并不喜欢它(上面的示例.name会出现在Red中),这使得它很难使用。

我正在使用Scala 2.10,现在无法改变。

2 个答案:

答案 0 :(得分:1)

使用与路径相关的返回类型注释您的返回类型,而不是依赖于推理:

def obvious[T <: DescriptionProvider](x: T): x.description.type = x.description

我用2.10.6制作了Scastie snippet,它似乎正在发挥作用。但是,我无法检查Intellij是否会抱怨。

答案 1 :(得分:0)

为什么不将name添加到Description特征:

trait Description {
  val name: String
}

trait DescriptionProvider {
  val description: Description
}

object Sample extends DescriptionProvider {
  object description extends Description {
    override val name: String = "foo"
  }
}

object Main extends App{

  def obvious[T <: DescriptionProvider](x: T) = x.description

  val description: String = obvious(Sample).name

  println(s"description = ${description}")

}

现在您可以编译并运行代码。将name添加到Description特征后,编译器就会知道Description有一个name