【问题标题】:How to make this Scala implicit conversion work?如何使这个 Scala 隐式转换工作?
【发布时间】:2011-12-09 21:32:34
【问题描述】:

我正在使用一个库,它为我提供以下信息(关系可以隐式转换为节点):

class Relation[A,B]
class Node[A,B](r: Relation[A,B])
implicit def relation2node[A,B](r: Relation[A,B]) = new Node(r)

我正在扩展 Relation 以供自己使用:

class XRelation[A] extends Relation[A,Int]

Relations/XRelations 应该被子类化:

class User extends XRelation[Int]

现在,我还定义了自己的 Helper 方法,例如 GET,旨在与任何 Node 以及任何转换为​​ Node 的东西一起工作:

class Helper[A,B](n: Node[A,B]) { def GET {} }

// note: this is the only way I know of to make the next example work.
implicit def xx2node2helper[A,B,C[_,_]](x: C[A,B])(implicit f: C[A,B] => Node[A,B]) = new Helper(x)

所以这个例子有效:

new Relation[Int,Int]().GET

如果我添加另一个隐式转换:

// don't understand why this doesn't work for the previous example
// but works for the next example
implicit def x2node2helper[A,B,C](x: C)(implicit f: C => Node[A,B]) = new Helper(x)

我还可以进行以下转换:

new XRelation[Int]().GET

但这不起作用:

new User().GET

遗憾的是,这失败了:

error: No implicit view available from Sandbox3.User => Sandbox3.Node[A,B]

谁能理解这一切并解释如何让最后一个示例工作?提前致谢。

更新:我知道你可以只从 Relation 引入隐式转换,但我要求 (1) 弄清楚如何做到这一点,而不必从每个单一类型中引入隐式可能会隐式转换为 Node,并且 (2) 巩固我对隐式的理解。

【问题讨论】:

    标签: scala implicit


    【解决方案1】:
    implicit def nodeLike2Helper[R, C <: R](r:C)(implicit f: R => Node[_,_]) = {
      new Helper(r)
    }
    

    正如错误消息所示,User 没有隐式转换为Node。但它的超超类Relation 有。因此,您只需为类型参数提供正确的界限。

    仅供参考,有一个语法糖&lt;% 用于视图边界,所以上面的代码可以更短:

    implicit def nodeLike2Helper[R <% Node[_,_], C <: R](r:C) = {
      new Helper(r)
    }
    

    【讨论】:

      【解决方案2】:

      在检查 User 是否匹配类型模式 C[_,_] 时,scala 分辨率仅进入一个超类深度。您可以通过取消以下代码中的模式来解决此问题。

      implicit def x2node2helper[A,B](x: Relation[A,B])(implicit f: Relation[A,B] => Node[A,B]) = new Helper(x)
      

      如果隐含的relation2node在x2node2helper的定义范围内,那么它可以写

      implicit def x2node2helper[A,B](x: Relation[A,B]) = new Helper(x)
      

      【讨论】:

      • 谢谢,但我要求 (1) 弄清楚如何做到这一点,而不必从每种可能隐式转换为 Node 的类型中引入隐含,以及 (2) 真正巩固我的对隐含的理解。澄清我的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 2021-02-24
      • 2018-11-19
      • 1970-01-01
      • 2013-09-28
      • 1970-01-01
      • 2015-08-13
      相关资源
      最近更新 更多