Скажем, я пишу метод расширения
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
Если вы всегда включаете extends AnyVal
в определение класса? При каких обстоятельствах вы не захотите сделать неявный класс классом значений?
Скажем, я пишу метод расширения
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
Если вы всегда включаете extends AnyVal
в определение класса? При каких обстоятельствах вы не захотите сделать неявный класс классом значений?
Посмотрите на ограничения указанные для классов значений, и подумайте, когда они могут не подходить для неявных классов:
"должен иметь только первичный конструктор с одним открытым параметром 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.Кроме того, если ваш неявный класс класс значения может изменить какое-либо поведение кода с помощью отражения, но отражение обычно не должно видеть неявные классы.
Если ваш неявный класс удовлетворяет всем этим ограничениям, я не могу думать о причине, чтобы не сделать его классом значений.
Я чувствую, что вы путаете классы значений с Неявные классы. Вы редко распространяете что-либо при определении неявного класса для повышения, тогда как классы значений должны расширять AnyVal
.