【发布时间】:2014-12-29 04:03:24
【问题描述】:
下面的代码sn-p取自thisScalaZ教程。
在评估代码示例底部的10.truthy 时,我无法弄清楚隐式解析规则是如何应用的。
我认为我确实理解的事情如下:
1) 隐式值intCanTruthy 是CanTruthy[A] 的匿名子类的一个实例,它根据以下规定为Int-s 定义了truthys 方法:
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 转换为具有truthy 方法的对象,因此它将尝试toCanIsTruthyOps 进行此转换。
3) 我怀疑当编译器尝试对10 进行toCanIsTruthyOps 隐式转换时,可能会以某种方式使用隐式值intCanTruthy。
但这是我真正迷路的地方。我只是看不到隐式解析过程在此之后如何进行。接下来发生什么 ?如何和为什么?
换句话说,我不知道在评估10.truthy时允许编译器找到truthy方法的实现的隐式解析序列是什么。
问题:
如何将10 转换为具有正确truthy 方法的对象?
那个对象是什么?
该对象将来自哪里?
有人可以详细解释,在评估10.truthy 时,隐式解析是如何发生的吗?
CanTruthy中的self-type{ self => ...是如何在隐式解析过程中发挥作用的?
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
【问题讨论】:
标签: scala implicit-conversion implicit scalaz