说我正在写一个扩展方法
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
你应该总是包含extends AnyVal
在类定义中吗?在什么情况下你不想让一个隐式类成为一个值类?
说我正在写一个扩展方法
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
你应该总是包含extends AnyVal
在类定义中吗?在什么情况下你不想让一个隐式类成为一个值类?
让我们看看为值类列出的限制,并思考它们何时可能不适合隐式类:
“必须只有一个主构造函数,其中只有一个公共的 val 参数,其类型不是值类。” 因此,如果您要包装的类本身就是一个值类,则不能使用 animplicit 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
s 或lazy val
s 的合理用例。此外,使您的隐式类成为值类可能会使用反射改变代码的某些行为,但反射通常不应该看到隐式类。
如果您的隐式类确实满足所有这些限制,我想不出不将其设为值类的理由。
我感觉到您将Value Classes与Implicit Classes混淆了。在为增强定义隐式类时,您很少扩展任何东西,而值类必须扩展AnyVal
。