如果隐性课程延长总是AnyVal?(Should implicit classes always e

2019-07-20 02:21发布

说我写的扩展方法

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

你应该总是包括extends AnyVal在类defininition? 在什么情况下,你不想让一个隐含的类值类?

Answer 1:

让我们来看看对价值类中列出的限制 ,并认为当他们可能不适合隐类:

  1. “只能有恰好与一个公开,VAL参数,其类型不是值类的主要构造。” 所以,如果你是包装类本身就是一个值类,你不能用一个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. “可能没有专门的类型参数。” 您可能需要包装本身有专门的类型参数的类时要专门包装。

  3. “不可能有嵌套或本地类,特质,或对象”同样,一些东西,可能是用于实现包装有用。
  4. “未必限定equalshashCode方法”。 无关紧要的,因为隐含的类也应该不会有equals/hashCode
  5. “必须是顶级类或静态访问对象的成员”这也是你通常定义隐含的类,但不是必需的。
  6. “只能有DEFS作为成员。特别是,它不能有懒惰瓦尔斯,乏,或瓦尔斯作为成员。” 隐类可以拥有所有这些,但我想不出一个合理的用例的var S或lazy val秒。
  7. “不能被其他类进行扩展。” 同样,隐含的类可以延长,但可能没有充分的理由。

此外,让您的隐含的类值类可能可能改变使用反射代码的某些行为,但反射通常不应该看到隐含的类。

如果您隐类并满足所有这些限制,我想不出理由不让它值类。



Answer 2:

我感觉你是混乱的价值类与隐性课程 。 定义隐班增强时,你会很少延长而任何价值类必须扩展AnyVal



文章来源: Should implicit classes always extend AnyVal?