「_」←下に横棒、これ何て読んでます?
アンダースコア、アンダーバー、下線、ちょっとマイナーどころだとアンダーライン、ローラインなんて読み方もあるそうです。
このサイトではアンダースコアと呼びますが、このアンダースコア、Kotlinの予約語の1つでもあります。
今回はどこで使われるかによって微妙に意味が異なる「アンダースコア」について。
(ちなみに動画投稿で生きている永遠の17歳はアンダーバーです)
動画投稿で生きる! フリーダムな仕事術 __(アンダーバー)自伝
コンストラクタ引数のアンダースコア
最初に「クラスのコンストラクタ引数」に使われるアンダースコア。
class Player(val name: String, _age: Int){
var age: Int = _age
fun squareAge(): Int = age * age
fun multiplyAge(n: Int): Int = age * n
}
2つ目のパラメータである_age
に注目してみましょう。名前がアンダースコアから始まっています。
はっきり言ってしまうと、このアンダースコア自体には特別な意味はありません。しかし無い場合と比べてみてください。
class Player(val name: String, age: Int){
var age: Int = age
fun square(): Int = age * age
fun multiply(n: Int): Int = age * n
}
どちらの方が引数とプロパティとを判別しやすいでしょうか?
引数の「age」とプロパティの「age」は型が違う別の値です。こんな風に名前が被ってしまうと、どちらがどちらの「age」なのか判別し難いという事態に陥ります。
このクラスにはageプロパティの値を使用するメソッドを2つ定義しています。しかし「_age」は引数とプロパティの初期化にしか使われていません。このように一時的にしか使われない変数はアンダースコアを頭に付けることで、
- 引数に取った値そのままであることが明確になる
- 引数とプロパティを明確に区別できる
といった利点があります。使用するかどうかはあくまで自由ですが、あった方が可読性が上がるのであれば適時使用しましょう。
数値のアンダースコア
こちらは簡単。桁が多い数値には、可読性向上のために任意の数のアンダースコアを付けることができます。
println(1_000_000_000)
//1000000000
ラムダ式のアンダースコア
上記2つとは別に、ラムダ式の引数にアンダースコアを使用する場合があります。
val example = mapOf(1 to "Kotlin", 2 to "Java")
example.forEach{(_, v)-> println(v)}
//Kotlin
//Java
forEach
はMap型から呼び出してラムダ式の引数を2つ設定すると、その要素であるPair型のキー/バリューをそれぞれ参照しますが、この例では第一引数をアンダースコアで表記しています。
このアンダースコアは「この引数は今後使用しない」という宣言です。
アンダースコアで表記された引数は、そのラムダ式内では使用できません。
example.forEach{(_, v)-> println(_)}
//エラー :Unresolved reference: _
//エラー :Names _, __, ___, ..., are reserved in Kotlin
文法的には問題無いようにも思えますが、アンダースコアはKotlinの予約語の1つ。「未使用」の宣言以外でのアンダースコアの使用はエラーになります。
分解宣言のアンダースコア
最後に分解宣言で利用されるアンダースコアです。
val (x, y, z) = Triple(1, 2, 3)
これは通常の分解宣言。左辺と右辺の値が同数であれば、右辺の値を複数の変数に一気に代入することができます。
val (_, y, z) = Triple(1, 2, 3)
左辺最初の変数をアンダースコアにした形。意味的にはラムダ式のときと同じ、「この部分は変数として利用しない」という宣言です。
この場合、変数yとzにはそれぞれ2と3が入ります。
val (x, _, z) = Triple(1, 2, 3)
2番目の値を使用しないならこの形。1と3が変数に代入されます。
val (x, y, _) = Triple(1, 2, 3)
val (x, y) = Triple(1, 2, 3)
最後の値を代入しない場合は記述自体を省略可能。上の2つは等価です。
参考文献
Kotlinのキーワード(予約語)と演算子一覧。
https://kotlinlang.org/docs/reference/keyword-reference.html
PairとTripleのAPIリファレンス。
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-pair/
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-triple/