Kotlin
| パラダイム | マルチパラダイム |
|---|---|
| 開発 | JetBrains |
| 発表日 | 2011年 |
| ホームページ | https://kotlinlang.org/ |
Kotlin(コトリン)は、JetBrains社によって開発された静的型付け言語である。
プログラム例
fun main() {
println("Hello, World!")
}
基本文法
Kotlin基本文法公式ドキュメントの内容を参考にしている。
パッケージ定義とインポート
パッケージ定義は常にファイルの先頭に配置する必要がある。
package my.demo
import kotlin.text.*
// ...
パッケージとフォルダ構造を一致させる必要はない。ファイルはファイルシステムのどこにあっても構わない。パッケージについての詳細はパッケージ公式ドキュメントを参照。
プログラムのエントリーポイント
Kotlinアプリケーションのエントリーポイントはmain関数である。
fun main() {
println("Hello world!")
}
関数
2つのInt引数を持ち、Int値を返す関数:
fun sum(a: Int, b: Int): Int {
return a + b
}
本体が式であり、戻り値の型推論を利用した関数:
fun sum(a: Int, b: Int) = a + b
戻り値がない関数:
fun printSum(a: Int, b: Int): Unit {
println("sum of $a and $b is ${a + b}")
}
戻り値の型Unitは省略可能:
fun printSum(a: Int, b: Int) {
println("sum of $a and $b is ${a + b}")
}
詳細は関数公式ドキュメントを参照。
変数
読み取り専用のローカル変数はvalキーワードを用いて定義する。読み取り専用変数は1回のみ値を初期化できる:
val a: Int = 1 // 定義と同時に初期化
val b = 2 // `Int`型が推論される
val c: Int // 初期化しない変数宣言は型を明示的に指定する必要がある
c = 3 // 遅延割り当て
読み書き可能な変数はvarキーワードを通じて定義する:
var x = 5 // `Int`型が推論される
x += 1
トップレベル変数:
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
詳細はプロパティとフィールド公式ドキュメントを参照。
コメント
他の現代的な言語と同様に、Kotlinも行コメントとブロックコメントを使用できる。
// これは一行コメント
/* これは複数行に
わたるブロックコメント */
ブロックコメントは入れ子にできる。
/* コメントはここで始まって
/* これは入れ子のコメント */
ここで終わる */
詳細はKotlinコードのドキュメント化公式ドキュメントを参照。
文字列テンプレート
var a = 1
// 基本的な変数名でテンプレートを使用
val s1 = "a is $a"
a = 2
// テンプレートに任意の式を入れる場合
val s2 = "${s1.replace("is", "was")}, but now is $a"
詳細は文字列テンプレート公式ドキュメントを参照。
条件式
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
Kotlinではifを式としても使用できる:
fun maxOf(a: Int, b: Int) = if (a > b) a else b
詳細はif式公式ドキュメントを参照。
Nullable値とnullチェック
参照型は必ずnullable形式で明示しなければnull値を使用できない。
str変数が整数文字列でない場合にnullを返す:
fun parseInt(str: String): Int? {
// ...
}
nullable値を返す関数を使用:
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// `x * y`をそのまま使用するとエラーが発生。xとyがnullの可能性があるため。
if (x != null && y != null) {
// nullチェックを行うと、xとyは自動的にnon-nullableにキャストされる
println(x * y)
}
else {
println("'$arg1' or '$arg2' is not a number")
}
}
詳細はNull安全性公式ドキュメントを参照。
型チェックと自動キャスト
is演算子は、対象の式が特定の型であるかチェックする演算子である。変更不可能なローカル変数やプロパティをチェックする場合、明示的にキャストする必要はない:
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj`はこの範囲において自動的にString型にキャストされる
return obj.length
}
// `obj`は型チェックの範囲外では依然としてAny型
return null
}
詳細はクラス公式ドキュメントと型キャスト公式ドキュメントを参照。
forループ
val items = listOf("apple", "banana", "kiwifruit")
for (item in items) {
println(item)
}
詳細はforループ公式ドキュメントを参照。
whileループ
val items = listOf("apple", "banana", "kiwifruit")
var index = 0
while (index < items.size) {
println("item at $index is ${items[index]}")
index++
}
詳細はwhileループ公式ドキュメントを参照。
when式
fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}
詳細はwhen式公式ドキュメントを参照。
範囲(Ranges)
数値が範囲内にあるかチェック:
val x = 10
val y = 9
if (x in 1..y+1) {
println("fits in range")
}
詳細はRanges公式ドキュメントを参照。
コレクション(Collections)
ラムダ式によるコレクションのフィルタ・マップ処理:
val fruits = listOf("banana", "avocado", "apple", "kiwifruit")
fruits
.filter { it.startsWith("a") }
.sortedBy { it }
.map { it.toUpperCase() }
.forEach { println(it) }
詳細はコレクション概要公式ドキュメントを参照。