配列
val ints = arrayOfNulls<Int>(5) //要素数が5でIntの配列を生成
ints[0] = 123
val strs = arrayOf("red","green","blue")
println(strs[0])
val ints2 : IntArray = intArrayOf(1,2,3)
println(ints2[0])
val chars : CharArray = charArrayOf('a','b')
println("${chars[0]}, ${chars[1]}")
//List
val intList : List<Int> = listOf<Int>(1,2,3)
//配列と違って要素の値を変更することができない。intList[0] = 5はコンパイルエラーとなる。
//インターフェースListはイミュータブルで、ミュータブルなリストはMutableListというインターフェースで表現されています。
var charList : MutableList<Char> = mutableListOf('a','b')
charList[0] = 'c'
//さらにMutableListは要素の追加や削除ができる
charList.add('x')
charList.remove('x')
charList.removeAt(0)
Map
val numberMap : MutableMap<String, Int> = mutableMapOf("one" to 1, "two" to 2)
println(numberMap["one"]) //1
println(numberMap["3"]) //キーに対応する値が存在しない場合はnullが返される
numberMap += "three" to 3
//レンジ
println(5 in 1..10) //true
val range :IntRange = 12..15
println(5 in range) //false
println(5 !in range) //true
//メソッドtoListを使用すると、レンジオブジェクトをリストオブジェクトに変換することができる
val r : IntRange = 1..5
val list : List<Int> = r.toList()
println(list) //[1,2,3,4,5]
//メソッドreversed
println(r.reversed().toList()) // [5,4,3,2,1]
//しかし、reversedを使うくらいなら最初からdownToをつかう
println((5 downTo 1).toList()) //[5,4,3,2,1]
//stepで刻む値をつけてやる
val stepList : List<Int> = (1..5 step 2).toList()
println(stepList) //[1,3,5]
val stepList2 : List<Int> = (100 downTo 0 step 25).toList()
println(stepList2) //[100, 75, 50, 25, 0]
条件分岐
if (5 in 1..10) {
println("5は1~10の範囲に入ってます")
}
val totalScore = 100
val message = if (totalScore >= 60) "合格!" else "不合格"
// ifやelseがブロックをとる場合、そのブロック内で最後に評価される式が返されます
val x = if (true) {
1
2
} else {
3
}
// x => 2
//if-elseチェーン
val score = 75
val grade = if (score >= 90) 'A'
else if (score >= 80) 'B'
else if (score >= 70) 'C'
else if (score >= 60) 'D'
else 'F'
// grade => C
When式
when式はJavaにおけるswitch文を強力にしたようなもの。
when (x) {
1 -> "one"
2 , 3 -> "two"
else -> {
"unknown"
}
}
//break必要なし、値を返すようなwhen式にはelseが必須
//条件分岐の部分に、定数以外を指定できる
when (x) {
1 -> "one"
myFavoriteInt() -> "favorite: $x"
in 2..10 -> "1 <= x <= 10"
else -> x.toString()
}
fun myFavoriteInt () : Int {
return 2
}
ループ制御
var count = 3
while (count-- > 0) {
println("hello")
}
do {
println("hello")
val next = Math.random() < 0.5
} while (next)
// forループ
for (x in arrayOf(1,2,3)) {
println(x)
}
// 1,2,3
for (i in 1..10 step 2) {
println(i)
}
// 1,3,5,7,9
関数
fun sub(minuend: Int, subtrahend:Int) : Int {
return minuend - subtrahend
}
//順番関係なしに名前付き引数でしていできる
sub(subtrahend = 10, minuend = 20)
可変長引数
varargをつけるだけ
fun sum(vararg ints : Int):Int {
var sum = 0
for (i in ints) {
sum += 1
}
return sum
}
//varargで指定された型Intは特化された配列クラス(IntArray)とみなされる
//コンパイラに可変長引数として、配列をわ明日ことを知らせるために、*記号を記述します
sum(*intArrayOf(1,2,3))
再起処理
スタックを消費しないように再起呼び出しを最適化してくれる仕組みがある
⇩
tailrecを最初につけて、関数の最後の計算が再起呼び出しであること、とする。
この仕組みをTCO(Tail Call Optimization)と呼ぶ関数オブジェクト
::をつけることで関数オブジェクトを取得できる(printlnなどで)
関数型
fun square(i:Int):Int = i * i
val functionObject: (Int) -> Int = ::square
ラムダ式
クロージャー
インライン関数