おはこんにちは!
エキサイトホールディングス新卒の奥田です!
本日は「Value Objectを使用する場合の、演算子の拡張について」について記事を執筆していきます。(Value Objectの利点等は今回の記事には含みません🙇♂️)
Value Objectの定義方法
KotlinではValue Objectを実現するために「value class」が用意されています。
用途としてはIntをより扱いやすくするため、新規にAge型として定義したい場合が該当します。
構文が下記のようになります。
@JvmInline
value class Age(val value: Int)
これで新規にValue Objectを作成することができました。
Value Objectを使用した演算子の拡張
演算子を使用する際の問題点として、既存の演算子が新規に定義したValue Objectに対応していない点が挙げられます。
/** Adds the other value to this value. */
public operator fun plus(other: Byte): Int
/** Adds the other value to this value. */
public operator fun plus(other: Short): Int
/** Adds the other value to this value. */
public operator fun plus(other: Int): Int
/** Adds the other value to this value. */
public operator fun plus(other: Long): Long
/** Adds the other value to this value. */
public operator fun plus(other: Float): Float
/** Adds the other value to this value. */
public operator fun plus(other: Double): Double
既存の定義には今回定義したValue Objectが定義されていないのが確認できます。
解決方法としてはValue Objectからvalue(今回はInt型)を取り出し扱います。
この実装では演算子を使用するたびにValue Objectから値を取り出してあげる必要があります。
class Sample() {
@JvmInline
value class Count(val value: Int)
private fun CountPlus(count: Count) {
count.value + 1
}
}
もう一つは演算子を拡張することで、Value Objectでの使用を実現する方法です。
演算子をよく使用する場合は拡張することで、コードの記述量を減らし、可読性も向上できるため下記のように実装するのをお勧めしたいです。
class Sample() {
@JvmInline
value class Count(val value: Int) {
operator fun plus(other: Int) = Count(value + other)
}
private fun CountPlus(count: Count) {
count + 1
}
}
まとめ
Value Objectを使用することでプリミティブ型を使用することができます。
しかし、新規に作成するため演算子を使用するタイミングで値を取り出し、使用する必要があります。
今回のようにValue Objectが演算に使われることが明確な場合は、演算子を定義してあげることで、Value Objectから値を取り出すことはなく便利に実装を進めることができます。
稚拙な文章でしたが最後まで読んでいただきありがとうございます✨