代入演算子

これまで説明することなく代入演算子を使ってきた。しかし前回++と—について取り上げたことだし、ここで代入演算子を取り上げておこう。

最も代表的な代入演算子は=だ。=の右側を先に評価し、その結果を左側の変数などに代入するというのがよく使われる方法だ。代入演算子の書き方をざっと書くと次のようになる。

代入演算子の使い方

代入可能式 代入演算子 値

代入演算子は=だけではなく、+=や-=といったものもある。PowerShell Coreで使われている代入演算子とその内容をまとめると次のようになる。

代入演算子 内容
= 変数の値を指定された値に設定
+= 指定された値だけ変数の値を増やす。指定された値を既存の値に追加する場合に使用する
-= 指定された値だけ変数の値を減らす。指定された値を既存の値から減算する場合に使用する
*= 指定された値を変数の値に乗算する。乗算の結果が代入される
/= 指定された値で変数の値を除算する。除算の結果が代入される
%= 指定された値で変数の値の剰余算を実施する。余りが変数に代入される
++ 変数、代入可能プロパティ、配列要素に1を加算する
変数、代入可能プロパティ、配列要素に1を減算する

前回も取り上げたが、インクリメント演算子の++やデクリメント演算子の—も代入演算子となる。単項演算子ということになり、書き方としては次のように前置型と後置型がある。前回も紹介したが、前置型と後置型では演算の優先順位というか処理の順序が異なるので注意が必要だ。

後置型のインクリメント/デクリメント演算子

代入可能式<演算子>

前置型のインクリメント/デクリメント演算子

<演算子>代入可能式

PowerShell Coreでは代入演算子を使って変数に代入を行う段階で対象変数が存在していなければ、そのタイミングで変数が作成される。すでに変数が存在する場合には上書きとなる。また、PowerShell Coreでは明示的に固定しない限り型の縛りは存在せず、代入元の型が変われば代入される変数の型も変わることになる。

代入演算子 =

たとえば次の例は代入演算子=を使って変数に値を割り当てたものだ。

代入後の型は動的に変化する

PS /Users/daichi> $v = 1
PS /Users/daichi> $v.GetType().FullName
System.Int32
PS /Users/daichi> $v = "str"
PS /Users/daichi> $v.GetType().FullName
System.String
PS /Users/daichi> $v = "a", "b", "c"
PS /Users/daichi> $v.GetType().FullName
System.Object[]
PS /Users/daichi> $v = @{a=1; b=2; c=3}
PS /Users/daichi> $v.GetType().FullName
System.Collections.Hashtable
PS /Users/daichi> $v = 1
PS /Users/daichi> $v.GetType().FullName
System.Int32
PS /Users/daichi> $v = 0x10
PS /Users/daichi> $v.GetType().FullName
System.Int32
PS /Users/daichi> $v = 1.01
PS /Users/daichi> $v.GetType().FullName
System.Double
PS /Users/daichi> $v = 1kb
PS /Users/daichi> $v.GetType().FullName
System.Int32
PS /Users/daichi> $v = "str"
PS /Users/daichi> $v.GetType().FullName
System.String
PS /Users/daichi> $v = "a", "b", "c"
PS /Users/daichi> $v.GetType().FullName
System.Object[]
PS /Users/daichi> $v = @{a=1; b=2; c=3}
PS /Users/daichi> $v.GetType().FullName
System.Collections.Hashtable
PS /Users/daichi>

PowerShell Coreは指定しない限り変数の型が固定されないので、代入される値の型が変わると、それに合わせて変数の型も変わっていることがわかる。

代入演算子 +=

代入演算子の中でもっとも機能が多いのが+=だ。

まず、基本的には次のような使い方となる。+=は変数に対して値を追加してから代入する演算子なので、次のように+=を使わずに=で代替することもできる。

代入演算子+=の基本的な使い方

PS /Users/daichi> $v = 1
PS /Users/daichi> $v += 2
PS /Users/daichi> $v
3
PS /Users/daichi> $v = 1
PS /Users/daichi> $v = $v + 2
PS /Users/daichi> $v
3
PS /Users/daichi>

次に文字列に対する+=だ。文字列に対して文字列を+=した場合、それは次のように文字列の結合を意味する。

代入演算子+=による文字列の結合

PS /Users/daichi> $v = "Hash"
PS /Users/daichi> $v += "table"
PS /Users/daichi> $v
Hashtable
PS /Users/daichi> :ew

+=は配列に対しても適用することができ、配列そのものに対して+=を実施すると、次のように配列の最後の要素として値を追加することになる。

+=を使った配列への値の追加

PS /Users/daichi> $v = 1,2,3
PS /Users/daichi> $v
1
2
3
PS /Users/daichi> $v += 2
PS /Users/daichi> $v
1
2
3
2
PS /Users/daichi> $v += "str"
PS /Users/daichi> $v
1
2
3
2
str
PS /Users/daichi>

+=はハッシュテーブルに対しても適用できる。ハッシュテーブルに対してはハッシュテーブルのみを利用することができ、指定したハッシュテーブルをハッシュテーブルに結合するといった処理になる。このため、すべての鍵が違っていることが処理の前提となる。

+=を使ったハッシュテーブルの結合

PS /Users/daichi> $v = @{a=1; b=2; c=3}
PS /Users/daichi> $v

Name                           Value
----                           -----
b                              2
c                              3
a                              1


PS /Users/daichi> $v += @{d="str"}
PS /Users/daichi> $v

Name                           Value
----                           -----
a                              1
c                              3
b                              2
d                              str


PS /Users/daichi>

このように、代入演算子の中では+=は操作対象が多岐にわたる。わかりにくくなることもあるので、配列とハッシュテーブルに関しては+=は使わないでメソッドを使うようにした方がよい場面もあるかもしれない。

代入演算子 -=

代入演算子は値を減算するものだ。次の処理を見るとわかりやすい。

代入演算子-=の基本的な使い方

PS /Users/daichi> $v = 1
PS /Users/daichi> $v -= 2
PS /Users/daichi> $v
-1
PS /Users/daichi> $v = 1
PS /Users/daichi> $v = $v - 2
PS /Users/daichi> $v
-1
PS /Users/daichi>

+=と異なり-=には配列やハッシュテーブルに対する処理はない(配列の要素に対して適用するといったことはできる)。

代入演算子 *=

代入演算子*=の基本的な使い方は次のようになる。乗算した結果を代入するというものだ。

代入演算子*=の基本的な使い方

PS /Users/daichi>
PS /Users/daichi> $v = 1
PS /Users/daichi> $v *= 5
PS /Users/daichi> $v
5
PS /Users/daichi> $v = 1
PS /Users/daichi> $v = $v * 5
PS /Users/daichi> $v
5
PS /Users/daichi>

+=ほどではないが、=の場合には対象が文字列だった場合の処理に注意が必要だ。次のように文字列に対して=を使用した場合、指定した回数分だけ文字列を複製して結合するという意味になる。

文字列に対して*=を使用した場合のサンプル

PS /Users/daichi> $v = "str"
PS /Users/daichi> $v *= 5
PS /Users/daichi> $v
strstrstrstrstr
PS /Users/daichi>

代入演算子 /=

代入演算子/=の使い方は-=と同じようにシンプルだ。指定した値で除算するというものだ。

代入演算子/=の基本的な使い方

PS /Users/daichi> $v = 1
PS /Users/daichi> $v /= 2
PS /Users/daichi> $v
0.5
PS /Users/daichi> $v = 1
PS /Users/daichi> $v = $v / 2
PS /Users/daichi> $v
0.5
PS /Users/daichi>

代入演算子 %=

代入演算子%=の使い方も基本的に次のようにシンプルになっている。

代入演算子%=の基本的な使い方

PS /Users/daichi> $v = 1
PS /Users/daichi> $v = 5
PS /Users/daichi> $v %= 2
PS /Users/daichi> $v
1
PS /Users/daichi> $v = 5
PS /Users/daichi> $v = $v % 2
PS /Users/daichi> $v
1
PS /Users/daichi>

%=というか基本的に剰余演算自体があまり使う機会がないかもしれない。奇数と偶数で処理を分けたい(たとえばテーブルの背景色を1行おきに変えたいとか)といったような場合に使うことがあるなど、ある程度プログラミングするようになってくると使う機会が出てくる機能ではないかと思う。

代入演算子 ++ —

++や—は変数とそれ単体で意味を持つ。$v++や++$vといった書き方をする。この基本的な使い方は次のとおり。

代入演算子++の基本的な使い方

PS /Users/daichi> $v = 1
PS /Users/daichi> ++$v
PS /Users/daichi> $v
2
PS /Users/daichi> $v = 1
PS /Users/daichi> $v++
PS /Users/daichi> $v
2
PS /Users/daichi> $v = 1
PS /Users/daichi> $v = $v + 1
PS /Users/daichi> $v
2
PS /Users/daichi>

上記サンプルはどれも同じ結果だが、++$vと$v++では処理の順序が異なっている。この違いはちゃんと理解しておく必要がある。

次のサンプルを見ると++$vと$v++の処理の違いがわかるだろう。$tの値がどのように違っているかに注目して読んでみてほしい。

前置型と後置型の処理優先順位の違い

PS /Users/daichi> $v = 1
PS /Users/daichi> $t = ++$v
PS /Users/daichi> $v
2
PS /Users/daichi> $t
2
PS /Users/daichi> $v = 1
PS /Users/daichi> $t = $v++
PS /Users/daichi> $v
2
PS /Users/daichi> $t
1
PS /Users/daichi>

++$vでは$vに値を1つ追加してから次の処理が行われている。$v++では処理が行われてから、つまり$tへ$vが代入されてから、$vへの値の追加が行われている。このあたりは繰り返し構文などを使う場合に特に重要になってくるので、処理の違いをよく理解しておきたい。

複数代入

PowerShell Coreには代入処理を1行にまとめて書くためのシンタックスシュガーが用意されている。次のような感じだ。次の処理で3つの個別の代入処理が1行にまとめられている。

3つの代入処理を1行にまとめて書いた場合

PS /Users/daichi> $a, $b, $c = 1, 2, 3
PS /Users/daichi> $a
1
PS /Users/daichi> $b
2
PS /Users/daichi> $c
3
PS /Users/daichi>

ただし、この書き方は少々注意が必要だ。次のような書き方をすると、最後の変数には残りの値が配列として代入されることになる。

あまった分は配列としてまとめて変数に代入される

PS /Users/daichi> $a, $b, $c = 1, 2, 3, 4, 5
PS /Users/daichi> $a
1
PS /Users/daichi> $b
2
PS /Users/daichi> $c
3
4
5
PS /Users/daichi>

逆に、配列から個別の変数に代入するといったこともできる。説明してもよくわからないと思うので、次のサンプルを見てほしい。

配列から個々の変数に代入

PS /Users/daichi> $v = 1, 2, 3
PS /Users/daichi> $v
1
2
3
PS /Users/daichi> $a, $b, $c = $v
PS /Users/daichi> $a
1
PS /Users/daichi> $b
2
PS /Users/daichi> $c
3
PS /Users/daichi>

次のような代入の仕方もできる。次のような書き方をした場合には、同じ値がすべての変数に代入されることになる。

同一の値をすべての変数に代入

PS /Users/daichi> $a = $b = $c = 1
PS /Users/daichi> $a
1
PS /Users/daichi> $b
1
PS /Users/daichi> $c
1
PS /Users/daichi> $a = $b = $c = 1, 2, 3
PS /Users/daichi> $a
1
2
3
PS /Users/daichi> $b
1
2
3
PS /Users/daichi> $c
1
2
3
PS /Users/daichi>

いくつもの代入処理を1行にまとめて書く機能は比較的最近のプログラミング言語には用意されている機能だ。

代入演算子はどこまで使えばよいのか

代入演算子=は当然ありとあらゆるシーンで使うことになるが、たとえば+=を使うべきか++を使うべきか+してから=で代入すべきか、結局このあたりはコーディングする人の好みによるところがある。

++や—に関しては目的がわかりやすいので、使ったほうが他の人が意図を汲み取りやすくなるような気はする。+=と-=はケースバイケースといったところだろうか。

あまり凝る必要はなく、基本的には=を使った方が後から読んでもわかりやすいことが多いので、積極的にいろんな代入演算子を使うようなことはしなくてよいだろう。

参考資料