- Contents -
まえがき
この記事では、Groovy3から新たに追加された演算子。
エルビス代入: Elvis assignment operator (?=
) というものを簡単に紹介しようと思います。
Elvis assignment operator
エルビス代入演算子とは、
変数がnullまたは、false (式としてfalse判定)だったら、右辺の値を代入しますよ。
という挙動になります。
if文による、nullチェックや、三項演算子で書くよりも簡素に書けるショートハンドとなります。
また、Groovyでは元々、
エルビス演算子(?:
)というものがありますが、今回お話するのはエルビス代入演算子(?=
)です。
旧来の書き方
// if文を使った代入
if (i == null) {
i = 100
}
// 三項演算子を使った代入
i = (i == null) ? 100 : i
// エルビス演算子を使った代入
i = i ?: 100
↑これらが、エルビス代入演算子を使うと、もっと簡素に書けるようになります。
// エルビス代入演算子を使った代入
i =? 100
より簡素になりました。
エルビス代入演算子の場合、
もし、変数が(null or false判定)じゃなかったなら、変数はそのままの値になります。
変数がfalse判定される時とは
エルビス代入演算子では、変数がnull、または式としてfalse判定される場合に、
代入されるので注意が必要です。
※変数がnullじゃなくても、false判定の場合には代入される。
例えば、下記条件であれば代入が発生します。
- int, Integerでは、ゼロだった場合にも代入が発生します。
- Stringは、空文字列(
""
)の場合にも、代入が発生します。 - リスト(
[]
)、マップ([:]
) の場合もサイズがゼロの場合に代入が発生します。
Truth Rulesについては、こちらのドキュメントを参照
http://groovy-lang.org/semantics.html#Groovy-Truth
Groovy decides whether a expression is true or false by applying the rules ...
エルビス代入のコード例
下記に、Elvis assignment operator の例を記載します。
Integer i = null
// エルビス代入 (nullの場合、代入される)
i ?= 100
assert 100 == i
Integer i = 0
// エルビス代入 (nullじゃないけど、false判定されるので代入される)
i ?= 100
assert 100 == i
Integer i = 200
// エルビス代入 (nullじゃない、false判定されない場合は、そのままの値)
i ?= 100
assert 200 == i
テストコード
いろんなパターンで動作確認してみましょう。
Spockによるテストコードを載せておきます。
for Integer
def "test elvis assignment for Integer"() {
when:
// エルビス代入
i ?= 100
then:
ret == i
where:
ret || i
100 || null // nullの場合は、代入される
100 || 0 // ゼロの場合でも、代入される
200 || 200 // 値が設定されてる場合は、元の値と同じ
}
for String
def "test elvis assignment for String"() {
when:
// エルビス代入
s ?= "Hello"
then:
ret == s
where:
ret || s
"Hello" || null // nullの場合は、代入される
"Hello" || "" // 空文字列は、false判定されるので代入される
"Groovy" || "Groovy" // 値が設定されてる場合は、元の値と同じ
}
for List
def "test elvis assignment for List"() {
when:
// エルビス代入
list ?= ["Hello"]
then:
ret == list
where:
ret || list
["Hello"] || null // nullの場合は、代入される
["Hello"] || [] // 空リストは、false判定されるので、代入される
["Groovy"] || ["Groovy"] // 値が設定されてる場合は、元の値と同じ
}
for Map
def "test elvis assignment for Map"() {
when:
// エルビス代入
map ?= [message: "Hello"]
then:
ret == map
where:
ret || map
[message: "Hello"] || null // nullの場合は、代入される
[message: "Hello"] || [:] // 空マップは、false判定されるので、代入される
[message: "Groovy"] || [message: "Groovy"] // 値が設定されてる場合は、元の値と同じ
}
上記のコードはGroovy 3.0.5. で動作確認しています。