Scala:如何使超类变量隐式在子类的作用域中



>想象一下,我有一些函数显式地接受字符串和隐式接受T:

object SomeNamespace {
def myFunction(arg: String)(implicit t: T)
}

我有一个提供 T 的超类

trait TProvider {
val t: T = ...
}

在我使用的子类中扩展 TProvider 并尝试使用该函数

class Child extends TProvider {
SomeNamespace.myFunction("somestring")
}

我会得到一个错误"找不到参数 t 的隐式值"。我的解决方法是将超类 val 重新分配给子类中的新隐式值,例如:

implicit val subclassImplicitT = t

这行得通...但有点丑。有没有更好的方法来"隐式"变量?

嗯...在已经声明之后"隐含"某些东西在 Scala 中并不容易做到。老实说,要么只是将其作为显式参数传入,要么可能是您最好的选择。这是一个充其量稍微好一点的替代方案。

trait TProvider {
// Yep it's gotta be a def for this to work, not a val,
// because you can't call super.t if t is a val
// (https://issues.scala-lang.org/browse/SI-1938)
def t: T
}
class Child extends TProvider {
// You can override it as a val though
override implicit val t = super.t
myFunction("something")
}

FWIW,我最终在我自己的项目中解决了这个问题,只需创建另一个隐含 t 的类 - 所以像

trait ImplicitTProvider {
implicit val t: T = ...
}

然后从该类而不是 TProvider 扩展。

这对这个项目是有意义的,因为我没有看到这些类中的任何一个变化太大。但也许不是一个很好的通用解决方案。

最新更新