>想象一下,我有一些函数显式地接受字符串和隐式接受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 扩展。
这对这个项目是有意义的,因为我没有看到这些类中的任何一个变化太大。但也许不是一个很好的通用解决方案。