ヌル合体演算子、ヌル合体代入演算子

今回も先日公開された「PowerShell 7 Preview 5」に導入された新機能を紹介しよう。今回取り上げるのは「ヌル合体演算子」と「ヌル合体代入演算子」だ。ヌル合体演算子はC#やSwiftなどに存在している演算子で、「変数がヌル(NULL)だった場合には指定した値を返し、そうでない場合には変数の値を返す」といった処理を行う場合に使用する。

PowerShell 7のヌル合体演算子は次のように記述する。

変数 ?? 値

「変数の値がヌルの場合にはこの値を使う」という手法は、よく使われるものだ。短くまとめたい場合には三項演算子を、基本にのっとるならif-else制御構文を使って書くが、ヌル合体演算子を使うと、そうした記述をかなり短く簡潔に済ませることができる。なお、ヌル合体演算子「??」はC#、Swift、PHP7などほかのプログラミング言語でも使われており、表記もまったく同じ「??」だ。

もう1つ紹介するのは、ヌル合体代入演算子「??=」だ。これは次のように表記する。

変数 ??= 値

ヌル合体代入演算子を使うと、変数がヌルだった場合に値を代入するといった、デフォルト値の代入のような処理を手短に記述することができる。この演算子はC# 8.0以降のC#に用意されており、C#からの”輸入”と考えるのが妥当なところだろう(参照: 「?? and ??= operators - C# reference | Microsoft Docs」。なお、「??=」の提案自体は2015年くらいには行われていたことが「Champion “Null-coalescing assignments” (16.3, Core 3) · Issue #34 · dotnet/csharplang」にて確認できる)。

前回のパイプラインチェイン演算子もそうだが、PowerShell 7 Preview 5で導入された機能はかゆいところに手が届くタイプの機能で、利用するとコードを短く簡潔にまとめることができるようになる。

ヌル合体演算子とヌル合体代入演算子を使ってみる

PowerShell 7 Preview 5で導入されたこの機能を早速使ってみよう。便利な機能なので早めに身につけてしまいたいところだ。まずは、ヌル合体演算子の処理を、if-else制御構文で処理した例を次に示す。

ヌル合体演算子を使わない場合のサンプル

きちんと読めば何を意図した処理なのかはわかる。ただパッと見で内容を理解するのは、ちょっと難しいのではないだろうか。

次に、同じ処理をヌル合体演算子を使った例を示す。

ヌル合体演算子を使った場合のサンプル

「『??』と書いてある行は、変数がヌルだった場合の処理を書いているんだな」ということがパッと見てわかる。これがヌル合体演算子を使う最も大きな利点ではないかと思う。

次のサンプルは、ヌル合体代入演算子を使ったものだ。

ヌル合体代入演算子を使った場合のサンプル

こちらも同じく、処理内容がパッと見でわかりやすい。

ただし、ヌル合体演算子とヌル合体代入演算子の使用の是非は、C#やPowerShell 7を知らないユーザーに対してもそのスクリプトの中身を提供するかどうか、による。これらの演算子は提供されていないプログラミング言語も多いので、読む人間によってはソースコードの読みにくさが増すことになるので注意が必要だ。

UNIX系シェルにおけるパラメータ展開時の書き換え機能

今回PowerShell 7 Preview 5に導入されたヌル合体演算子とヌル合体代入演算子と、まったく同じ機能ではないものの、パラメータ展開時に似たような処理を行う記述がUNIX系のシェルにも用意されている。

■変数がヌルだった場合に値を使う

${変数名:-値}

■変数がヌルだった場合に変数に値を代入しつつ、値を使う

${変数名:=値}

この機能を使用すると、変数が使われていない、またはヌルの場合に利用するデフォルト値を指定しておくことができる。ヌル合体演算子やヌル合体代入演算子で行う処理とよく似ている。

UNIX系のシェルで実行したサンプルを次に示す。

UNIX系シェルのパラメータ展開時の編集機能を利用した場合

PowerShellはUNIX系のシェルの影響を強く受けている。特にそのUIや使い方をUNIX系のシェルに寄せており、前回のパイプラインチェイン演算子などもその1つということになる。ただし、プログラミング言語の特徴としてはC#の影響を強く受けていることを考えると、PowerShellにC#の機能が導入されるのは自然な流れだ。

これまでの機能の変遷を見ていくと、もしかするとそのうち、UNIX系シェルにおけるパラメータ展開時の書き換え機能、つまり「${変数名:-値}」や「${変数名:=値}」といった表記がPowerShell 7、またはそれ以降のバージョンで使えるようになるかもしれない。合わせて覚えておいて損のない書き方だろう。

参考資料