scala:将隐式参数覆盖到构造函数 [英] scala: override implicit parameter to constructor

查看:48
本文介绍了scala:将隐式参数覆盖到构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类接受一个隐式参数,该参数由在类方法内部调用的函数使用.我希望能够覆盖该隐式参数,或者从其源复制隐式参数.举个例子:

I have a class that takes an implicit parameter which is used by functions called inside class methods. I want to be able to either override that implicit parameter, or alternatively, have the implicit argument be copied from its source. As an example:

def someMethod()(implicit p: List[Int]) {
  // uses p
}

class A()(implicit x: List[Int]) {

  implicit val other = List(3) // doesn't compile

  def go() { // don't want to put implicit inside here since subclasses that override go() have to duplicate that
    someMethod()
  }
}

我想要的行为是 someMethod() 获取一个隐式参数,该参数是 x 的某个更改版本,它是类的隐式参数.我希望能够改变 x 而不改变它传递给 A 的构造函数的任何内容,或者以其他方式将其覆盖为我选择的新值.这两种方法似乎都不起作用.也就是说,在前一种情况下它不会复制列表,并且编译器会为后一种情况找到一个不明确的隐式值.有没有办法做到这一点?

The behavior I want is that someMethod() gets an implicit parameter that is some changed version of x, which was the class's implicit parameter. I want to be able to either mutate x without changing it for whatever passed it into A's constructor, or otherwise override it to a new value of my choosing. Both approaches don't seem to work. That is, it doesn't copy the list in the former case, and the compiler finds an ambiguous implicit value for the latter case. Is there a way to do this?

我意识到我可以在 go() 中重新定义隐式值,但在我的情况下这不是一个好的选择,因为这个类被多次子类化,我只想在基类中处理这种隐式更改.所以不一定要在构造函数中,但必须在go()以外的方法中.

I realize that I can redefine the implicit value within go(), but this is not a good choice in my case because this class is subclassed numerous times, and I'd like to handle this implicit change in the base class only. So it doesn't necessarily need to go in the constructor, but it must be in a method other than go().

推荐答案

引入另一种包装器类型,只是为了消除歧义:

Introduce another wrapper type, simply to disambiguate:

//  badly named, choose something domain-specific
case class ListHolder(theList: List[Int])

def someMethod()(implicit holder: ListHolder) {
  val xs = holder.theList
  // uses xs ...
}

class A()(implicit xs: List[Int]) {

  implicit val other = ListHolder(42 :: xs) // compiles

  def go() {
    // xs is never considered for the implicit param to someMethod()
    // because it's now the wrong type
  }
}

这也使代码更具自文档性,因为两个隐式完全相同,这变得非常明显.

This also makes the code more self-documenting, as it becomes blindingly obvious that the two implicits are not one and the same.

这篇关于scala:将隐式参数覆盖到构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆