我注意到,当我尝试创建fooSemigroup的实例时,在第一个版本中,匿名函数创建了fooSemigroup的实例而没有实例化Foo的成员,但是当我尝试在没有SAM构造的情况下执行此操作时,为SemigroupOps创建foo的虚拟实例,以提取隐式值ev
。
trait Semigroup[A] {
def combine(x: A, y: A): A
}
case class Foo(v: Int)
// vs 1
implicit val fooSemigroup: Semigroup[Foo] = (x: Foo, y: Foo) => Foo(x.v + y.v)
// vs 2
implicit class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
implicit val f: fooSemigroup = Foo(0)
implicit class SemigroupOps[A](x: A) {
def +(y: A)(implicit ev: Semigroup[A]): A = ev.combine(x, y)
}
代替隐式类
implicit class fooSemigroup(foo: Foo) extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}
尝试隐式对象
implicit object fooSemigroup extends Semigroup[Foo] {
def combine(x: Foo, y: Foo) = Foo(x.v + y.v)
}