implicit def を使って、Scala で null 結合演算子を実現してみた
Scala の implicit def を利用して、C# などにある null 結合演算子を実現してみました。null 結合演算子というのは、対象としている値が null だった場合に別の値を返す演算子です。*1
たとえば以下の C# コードでは、value3 の "foo" が表示されます。
string value1 = null; string value2 = null; string value3 = "foo"; string value4 = "bar"; Console.WriteLine(value1 ?? value2 ?? value3 ?? value4);
さて、この機能を implicit def を使用して Scala でも実現してみました。以下のコードになります。
object NullCoalescingOperator { implicit def anyRefToNullCoalescingOperator[T<:AnyRef](value: T) = new NullCoalescingOperator(value) class NullCoalescingOperator[T<:AnyRef](value: T) { def ??(default: =>T) = if (null != value) value else default } def main(args: Array[String]) = { val value1: String = null val value2: String = null val value3: String = "foo" val value4: String = "bar" println(value1 ?? value2 ?? value3 ?? value4) } }
実行すると、ちゃんと "foo" が出力されました。
この null 結合演算子ですが && や || と同じように、値が確定したところで評価をやめます。なので、以下のコードを実行すると、"[expr value4]"は出力されません。
def main(args: Array[String]) = { val value1: String = null val value2: String = null val value3: String = "foo" val value4: String = "bar" println({println("[expr value1]");value1} ?? {println("[expr value2]");value2} ?? {println("[expr value3]");value3} ?? {println("[expr value4]");value4}) }
実行結果は以下のとおり。
[expr value1]
[expr value2]
[expr value3]
foo
やはり、Scala は強力だなぁ・・・とおもった今日この頃。
補足
implicit def ですが、機能の名称としては implicit conversion ですね。ド忘れしてました(汗