扩展具有需要隐式成员的特征的对象

Extending an object with a trait which needs implicit member

我正在尝试使用如下代码:

object MetaData extends CacheParams{}

所以,由于 CacheParams 需要 implicit val p:Parameters,我试过:

object MetaData (implicit val p: Parameters) extends CacheParams

但我似乎无法将参数传递给对象。

(因为它给出了错误:traits or objects may not have parameters

如果我不传递任何参数,它会给出编译错误:

[error]: object creation impossible, since value p in trait CacheParams of type Parameters is not defined

我不知道如何让它工作。有几个类似的问题,但是 none 他们的回答解决了我的问题。任何帮助将非常感激。 非常感谢。

如果我猜对了CacheParams的定义

trait Parameters

trait CacheParams {
  implicit val p: Parameters
}

那么你应该:(1) 替换对象

object MetaData /*(implicit val p: Parameters)*/ extends CacheParams

//object creation impossible. Missing implementation for:
//  implicit val p: Parameters // inherited from trait CacheParams

有 class

class MetaData(implicit val p: Parameters) extends CacheParams

或(2)在对象内部实现隐式

object MetaData extends CacheParams {
  override implicit val p: Parameters = new Parameters {}
}

implicit val params: Parameters = new Parameters {} // suppose an implicit is in current scope

object MetaData extends CacheParams {
  override implicit val p: Parameters = {
    val p = ??? // hiding above p to avoid ambiguous implicits, null or NPE, see (*) below
    implicitly[Parameters]
  }
}

(*)

在 (1) 中,您现在 defining/resolving 隐含在当前范围内。在 (2) 中,您推迟解析隐式直到实例化 class(在 class 构造函数调用站点的范围内解析隐式)。

另见

Yeah that would solve my problem. But I wanted to keep the object's body clean and decoupled from the configuration in Parameters, like the classes' bodies that accept the p: Parameters.

如果在 (1) 中你想将对象与“Parameters 中的配置”分离,你可以尝试引入一个特征 (ParamsMaterializer):

object MetaData extends CacheParams with ParamsMaterializer

trait ParamsMaterializer {
  implicit val p: Parameters = new Parameters {}
}

implicit val params: Parameters = new Parameters {} // suppose an implicit is in current scope

object MetaData extends CacheParams with ParamsMaterializer

trait ParamsMaterializer {
  implicit val p: Parameters = {
    val p = ???
    implicitly[Parameters]
  }
}