隐式类与隐式转换为特征

Mar*_*tti 7 scala implicit-conversion

我正在尝试向现有类型添加新功能(因此我可以让IDE自动为我无法控制的类型建议相关功能,例如Future[Option[A]]).我已经探索了隐式类和隐式转换来实现这一点,它们似乎都提供了相同的行为.

使用隐式类之间是否有任何有效的区别:

case class Foo(a: Int)
implicit class EnrichedFoo(foo: Foo) {
  def beep = "boop"
}
Foo(1).beep // "boop"
Run Code Online (Sandbox Code Playgroud)

并使用隐式转换:

case class Foo(a: Int)
trait Enriched {
  def beep: String
}
implicit def fooToEnriched(foo: Foo) = new Enriched {
  def beep = "boop"
}
Foo(1).beep // "boop"
Run Code Online (Sandbox Code Playgroud)

我想这里的一个区别可能是第一个例子创建了一个一个类而不是一个特征,但是我可以很容易地调整隐式类来扩展一个抽象特征,例如:

case class Foo(a: Int)
trait Enriched {
  def beep: String
}
implicit class EnrichedFoo(foo: Foo) extends Enriched {
  def beep = "boop"
}
Foo(1).beep // "boop"
Run Code Online (Sandbox Code Playgroud)

Luk*_*itz 7

据我所知,它们几乎完全一样.范围规则同样适用于两者.

在我看来,我会用implicit classes你的情况.它们可能就是为了类似的东西创建的.

对我来说,隐式转换更合适,因为当你已经实际拥有两种不同类并想要在两者之间进行转换时.

您可以在此处查看隐式类的初始提议. 它说:

提出了一种新的语言结构来简化类的创建,这些类为另一种类型提供扩展方法.

你甚至可以看到它如何消亡implicit classes.下列:

implicit class RichInt(n: Int) extends Ordered[Int] {
   def min(m: Int): Int = if (n <= m) n else m
   ...
}
Run Code Online (Sandbox Code Playgroud)

将desugar:

class RichInt(n: Int) extends Ordered[Int] {
  def min(m: Int): Int = if (n <= m) n else m
  ...
}
implicit final def RichInt(n: Int): RichInt = new RichInt(n)
Run Code Online (Sandbox Code Playgroud)

  • 还有一点需要注意的是,当你想隐式地将类型A的对象转换为类型B的对象,其中B是*`final class`*时,"隐式def"是你唯一的选择. (2认同)