我有这样的类型层次结构:
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,现在无法改变。
答案 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
。