拡張メソッドを書いているとしましょう
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
常に含める必要がありますextends AnyVal
クラス定義内?暗黙的なクラスを値クラスにしたくないのはどのような場合ですか?
値のクラスにリストされている制限 を見て、それらが暗黙のクラスに適していない場合があることを考えてみましょう。
「タイプが値クラスではないpublic valパラメータを1つだけ持つプライマリコンストラクタのみが必要です。」したがって、ラップしているクラス自体が値クラスの場合、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
sやlazy val
sの賢明なユースケースは考えられませんが、暗黙的なクラスはそれらすべてを持つことができます。さらに、暗黙クラスを値クラスにすると、リフレクションを使用してコードの動作が変更される可能性がありますが、リフレクションでは通常、暗黙クラスが表示されません。
暗黙のクラスがこれらの制限をすべて満たしている場合、それを値クラスにしない理由は考えられません。
Value Classes と Implicit Classes を混同しているように思います。値クラスmustがAnyVal
を拡張する一方で、拡張機能の暗黙クラスを定義する場合、ほとんど何も拡張しません。