说我正在写一个扩展方法
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
您是否应始终在课程定义中包含extends AnyVal
?在什么情况下你不想让隐式类成为值类?
答案 0 :(得分:48)
让我们看看limitations listed for value classes,并考虑它们何时可能不适合隐式类:
“必须只有一个主构造函数,其中只有一个public,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
}
“可能没有专门的类型参数。”在包装一个本身具有专用类型参数的类时,您可能希望包装器是专用的。
equals
或hashCode
方法。”不相关,因为隐式类也不应该有equals/hashCode
。var
或lazy val
s的合理用法。此外,使隐式类成为值类可能会使用反射更改某些代码行为,但反射通常不应该看到隐式类。
如果你的隐式类确实满足所有这些限制,我就不会想到不使它成为值类的原因。
答案 1 :(得分:0)
我觉得你让Value Classes和Implicit Classes混淆了。在为增强定义隐式类时,您很少扩展任何内容,而值类必须扩展AnyVal
。