拡張メソッドを書いているとしましょう
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
extends AnyVal
クラス定義に常に含める必要がありますか? 暗黙のクラスを値クラスにしたくないのはどのような状況ですか?
拡張メソッドを書いているとしましょう
implicit class EnhancedFoo(foo: Foo) {
def bar() { /* ... */ }
}
extends AnyVal
クラス定義に常に含める必要がありますか? 暗黙のクラスを値クラスにしたくないのはどのような状況ですか?
値クラスについてリストされている制限を見て、それらが暗黙のクラスに適していない場合を考えてみましょう。
「型が値クラスではない、正確に 1 つの 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
s やs の賢明なユースケースは思いつきませんが、暗黙のクラスはそれらすべてを持つことができますlazy val
。さらに、暗黙的なクラスを値クラスにすると、リフレクションを使用してコードの動作が変わる可能性がありますが、リフレクションは通常、暗黙的なクラスを認識しないはずです。
暗黙のクラスがこれらの制限をすべて満たしている場合、それを値クラスにしない理由は考えられません。