这个“简单”ScalaZ教程代码示例中的隐式解析序列是什么?
下面的代码片段取自
this ScalaZ教程.
在评估代码示例底部的10.truthy时,我无法弄清楚隐式解析规则是如何应用的. 我认为 – 我明白的事情如下: 1)隐含值intCanTruthy是CanTruthy [A]的匿名子类的实例,它根据以下内容定义Int-s的factys方法: scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({ case 0 => false case _ => true }) intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051 2)当评估10.truthy时,toCanIsTruthyOps隐式转换方法在范围内,因此当编译器看到Int没有truthy方法时,它将尝试使用这种隐式转换方法.因此编译器将尝试寻找一些隐式转换方法,该方法将10转换为具有真实方法的对象,因此它将尝试将此转换为此转换. 3)我怀疑当编译器在10上尝试toCanIsTruthyOps隐式转换时,可能会以某种方式使用隐式值intCanTruthy. 但这是我真正迷失的地方.我只是没有看到隐含的解决方法过程如何进行.接下来发生什么 ?怎么样,为什么? 换句话说,我不知道什么是隐式解析序列,它允许编译器在评估10.truthy时找到truthy方法的实现. 问题: 如何将10转换为具有正确真实方法的某个对象? 那个对象是什么? 那个对象来自哪里? 有人可以详细解释在评估10.truthy时隐式解决方案是如何发生的吗? self-type如何{self => … CanTruthy在隐式解决过程中发挥作用? scala> :paste // Entering paste mode (ctrl-D to finish) trait CanTruthy[A] { self => /** @return true,if `a` is truthy. */ def truthys(a: A): Boolean } object CanTruthy { def apply[A](implicit ev: CanTruthy[A]): CanTruthy[A] = ev def truthys[A](f: A => Boolean): CanTruthy[A] = new CanTruthy[A] { def truthys(a: A): Boolean = f(a) } } trait CanTruthyOps[A] { def self: A implicit def F: CanTruthy[A] final def truthy: Boolean = F.truthys(self) } object ToCanIsTruthyOps { implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A]) = new CanTruthyOps[A] { def self = v implicit def F: CanTruthy[A] = ev } } // Exiting paste mode,now interpreting. defined trait CanTruthy defined module CanTruthy defined trait CanTruthyOps defined module ToCanIsTruthyOps 尝试10上的类型类: scala> import ToCanIsTruthyOps._ import ToCanIsTruthyOps._ scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({ case 0 => false case _ => true }) intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051 scala> 10.truthy res6: Boolean = true 解决方法
首先,感谢您粘贴一个完全独立的示例.
当对类型A不提供该方法的值调用方法时,必须启动隐式转换,即必须在范围内具有签名A =>的方法或函数. B与B具有所讨论的方法(真理).在转换方法的情况下,它可能要求额外的隐含参数,这些参数将被相应地查找. 转换方法是CanIsTruthyOps,通过导入ToCanIsTruthyOps的内容使其可用.上述句子中的B型是CanTruthyOps,转换方法是CanIsTruthyOps.只要找到隐式类型类证据参数CanTruthy,它就可以被编译器调用.因此,由于类型A = Int,如果调用10.truthy将成功,编译器必须找到CanTruthy [Int]类型的隐式值. 它在几个地方寻找这样的价值.它可能位于Int(不存在)的伴随对象或CanTruthy的伴随对象中,或者显式导入到当前范围中.这里使用最后一种情况.您明确创建了隐式值intCanTruthy,现在找到该值.就是这样.
将有一个CanTruthyOps的临时实例,其目的仅仅是在证据类型类值上调用factys(这里是你的intCanTruthy).
它在查找隐式转换时发现Int => CanTruthyOps [INT].转换执行该对象的实例化.
请参阅上面第一个问题的答案.或者作为显式代码: type A = Int val v: A = 10 val ev: CanTruthy[A] = intCanTruthy val ops: CanTruthyOps[A] = ToCanIsTruthyOps.toCanIsTruthyOps(v)(ev) ops.truthy
它与隐式解决方案无关.事实上,在你的特征CanTruthy的例子中,self充当了它的别名,甚至没有被使用,所以你可以删除它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |