可以暗示改变呼叫站点方法的参数多样性吗?

时间:2014-06-11 21:44:45

标签: scala parameters implicit

我的API原型如下:

我有名为ZResponseHandler的第三方API对象,其中包含方法

printZ(z:Z) 

不,我有以下内容:

case class X
case class Y 
case class Z(x:X,y:Y)

现在,当我使用我的API调用printZ方法和新的z实例时,它可以正常工作。

ZResponseHandler.printZ(new Z(x,y))

但我想创建这样的东西:

implicit def convertXYtoZ(x:X,y:Y):Z = new Z(x,y)

ZResponseHandler.printZ(x,y)

此代码为我提供了编译错误- too many arguments for method printZ:

有没有办法让任何隐式类接受printZ(x,y)?

2 个答案:

答案 0 :(得分:2)

Implicits可以用 wrap "pimp"接收器用更多方法来装饰它。

class R {
  def m (s: String) = println(s)
}

// This uses an anonymous type, but it could also return
// `new RichR(r)` or similar as appropriate.
implicit def toRichR(r: R) = new {
    def m(a: String, b: String) = r.m(a + " " + b)
}

val r = new R()
r.m("hello", "world") // -> toRichR(r).m("hello", "world")

Implicit classes(Scala 2.10+)也允许更清楚地写出上述模式。

implicit class RichR(r: R) {
    def m(a: String, b: String) = r.m(a + " " + b)
}

对象也可能是" pimped"在Scala 2.10(但不是2.8)

object R {
  def m (s: String) = println(s)
}

// uses TheObject.type
implicit def toRichR(_r: R.type) = new {
    // (could use _r.m instead of R.m)
    def m(a: String, b: String) = R.m(a + " " + b)
}

R.m("hello", "world") // -> toRichR(r).m("hello", "world")

(也有隐含的对象,但如果没有常见的[非对象]基类型,我就无法工作。)

答案 1 :(得分:2)

隐式方法将转换单个参数,因此您无法更改arity(参数数量)。但是,您可以使用元组来解决这个问题:

implicit def convertXYtoZ(t: (X,Y) ):Z = new Z(t._1, t._2)
ZResponseHandler.printZ(x,y)