隐式类应该总是扩展AnyVal?

假设我在写一个扩展方法

implicit class EnhancedFoo(foo: Foo) { def bar() { /* ... */ } } 

你是否总是在类定义中包含extends AnyVal AnyVal? 在什么情况下你不想让隐式类成为一个价值类?

让我们来看看为值类所列出的限制,并认为它们可能不适合隐式类:

  1. “只能有一个主构造函数,只有一个publictypes的val参数的types不是值类”。 所以,如果你正在包装的类本身是一个值类,你不能使用implicit class作为包装,但你可以这样做:

     // wrapped class class Meters(val value: Int) extends AnyVal { ... } // wrapper class RichMeters(val value: Int) extends AnyVal { ... } object RichMeters { implicit def wrap(m: Meter) = new RichMeter(m.value) } 

    如果你的包装也有隐式参数,你可以尝试将它们移到方法声明中。 即,而不是

     implicit class RichFoo[T](foo: Foo[T])(implicit ord: Ordering[T]) { def bar(otherFoo: Foo[T]) = // something using ord } 

    你有

     implicit class RichFoo[T](foo: Foo[T]) extends AnyVal { def bar(otherFoo: Foo[T])(implicit ord: Ordering[T]) = // something using ord } 
  2. “可能没有专门的types参数”。 当包装一个本身具有特定types参数的类时,你可能希望包装器是专用的。

  3. “可能没有嵌套的或局部的类,特性或对象”再一次,可能对实现包装器很有用。
  4. “不能定义一个equals或者hashCode方法”。 不相关的,因为隐式类也不应该有equals/hashCode
  5. “必须是顶级类或静态可访问对象的成员”这也是通常定义隐式类的地方,但不是必需的。
  6. “只能成为成员,特别是不能有懒惰的瓦尔,瓦尔或瓦尔成员。” 隐式类可以包含所有这些,但我想不出一个明智的用于var s或lazy val s的用例。
  7. “不能由另一个class级扩展”。 同样,隐式类可以扩展,但可能没有什么好的理由。

另外,让隐式类成为一个值类可能会改变一些使用reflection的代码行为,但reflection通常不会看到隐式类。

如果你的隐式类确实满足了所有这些限制,我想不出一个理由不把它变成一个价值类。

我感觉到你在使用隐式类来混淆值 类 。 为增强定义隐式类时,您几乎不会扩展任何内容,而值类必须扩展AnyVal