Hello World と基本
Kotlin プログラムはトップレベルの main 関数から始まります。クラスは不要です。
| 構文 | 意味 |
|---|
fun main() { println("Hello") } | プログラムのエントリポイント |
println("text") | 標準出力に1行出力する |
print("text") | 末尾の改行なしで出力する |
// comment | 1行コメント |
/* comment */ | 複数行コメント |
val input = readLine() | stdin から1行読む (nullable な String?) |
val line = readln() | stdin から1行読む (非 null、Kotlin 1.6+) |
変数 (val / var) と型
val を優先し、値が変わる必要があるときだけ var を使う。
| 構文 | 意味 |
|---|
val name = "Ada" | 読み取り専用の変数、型は String と推論される |
var count = 0 | 可変の変数 |
val age: Int = 30 | 明示的な型注釈 |
Int, Long, Double, Float | 数値型 (42, 42L, 3.14, 3.14f) |
Boolean, Char, String | true/false, 'a', "text" |
val big = 1_000_000 | 読みやすいリテラルのためのアンダースコア |
"3".toInt(), "2.5".toDouble() | 文字列を数値に変換する |
42.toString() | 数値を文字列に |
const val MAX = 10 | コンパイル時定数 (トップレベルまたは object 内) |
文字列とテンプレート
文字列テンプレートはほぼすべての場面で連結の代わりになります。
| 構文 | 意味 |
|---|
"Hi, $name" | 文字列に変数を埋め込む |
"Total: ${price * qty}" | 式を埋め込む |
s.length | 文字数 |
s.uppercase(), s.lowercase() | 大文字・小文字を変える |
s.trim() | 前後の空白を取り除く |
s.contains("x"), s.startsWith("a") | 文字列内を検索する |
s.substring(0, 3) | インデックス範囲で切り出す |
s.split(",") | List<String> に分割する |
s[0] | 指定インデックスの文字 |
"""raw text""" | エスケープ不要の複数行生文字列 |
"%.2f".format(3.14159) | 書式付き出力 (3.14) |
null安全
型はデフォルトで非 null。? を付けると null を許容し、コンパイラがその処理を強制します。
| 構文 | 意味 |
|---|
var s: String? = null | nullable な型 |
s?.length | 安全呼び出し: s が null なら null を返す |
s?.length ?: 0 | エルビス演算子: null のときの代替値 |
s!!.length | 非 null アサーション: s が null なら例外を投げる |
if (s != null) s.length | チェック内で非 null にスマートキャスト |
s?.let { println(it) } | null でないときだけブロックを実行 |
val n = s?.toIntOrNull() | 変換し、不正な入力なら null |
lateinit var x: String | 後から初期化する非 null の var |
演算子
| 演算子 | 意味 |
|---|
+ - * / % | 算術演算 (Int 同士の / は整数除算) |
+= -= *= /= %= | 複合代入 |
++ -- | インクリメント / デクリメント |
== != | 構造的等価 (equals を呼ぶ) |
=== !== | 参照等価 (同じオブジェクト) |
< > <= >= | 比較 |
&& || ! | 論理積 / 論理和 / 否定 |
a in 1..10 | 範囲またはコレクションへの所属 |
x as Int, x as? Int | キャスト / 安全なキャスト (失敗時は null) |
x is String | 型チェック (成功時はスマートキャスト) |
制御フロー (if / when)
if と when は式であり、値を返します。
| 構文 | 意味 |
|---|
if (a > b) x else y | 式としての if (Kotlin に三項演算子 ?: はない) |
if (c) { ... } else if (d) { ... } else { ... } | 連鎖する分岐 |
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" } | 値と照合する |
when (x) { 1, 2 -> "low" } | 1つの分岐に複数の値 |
when (x) { in 1..9 -> "digit" } | 範囲と照合する |
when (x) { is String -> x.length } | 型と照合する (スマートキャスト付き) |
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" } | 対象なしの when、if/else if と同様 |
val label = when (x) { ... } | 式としての when (else が必要) |
ループと範囲
| 構文 | 意味 |
|---|
for (i in 1..5) | 1 から 5 までの閉区間 |
for (i in 1 until 5) | 1 から 4 まで (終端を含まない) |
for (i in 0..<5) | 同じ、終端を含まない範囲の構文 (Kotlin 1.9+) |
for (i in 10 downTo 1 step 2) | ステップ付きでカウントダウン |
for (item in list) | コレクションを反復する |
for ((i, item) in list.withIndex()) | インデックスと要素を同時に |
for (ch in "abc") | 文字列の文字を反復する |
while (cond) { ... } | 真である間ループする |
do { ... } while (cond) | 少なくとも1回実行する |
break, continue | ループを抜ける / 次の反復へ進む |
repeat(3) { println(it) } | ブロックを n 回実行する |
関数
| 構文 | 意味 |
|---|
fun add(a: Int, b: Int): Int { return a + b } | 関数を宣言する |
fun add(a: Int, b: Int) = a + b | 単一式関数、戻り値の型は推論される |
fun greet(name: String = "world") | パラメータのデフォルト値 |
greet(name = "Ada") | 名前付き引数 |
fun log(vararg items: String) | 可変長引数 |
fun say(): Unit | 戻り値なし (Unit は省略可) |
val square = { x: Int -> x * x } | 変数に格納したラムダ |
fun String.shout() = uppercase() + "!" | 拡張関数 |
fun apply(f: (Int) -> Int) = f(2) | パラメータとしての関数 |
list.map { it * 2 } | 末尾ラムダ、it が唯一のパラメータ |
リスト
listOf は読み取り専用、mutableListOf は変更可能。
| 構文 | 意味 |
|---|
val nums = listOf(1, 2, 3) | 読み取り専用リスト |
val items = mutableListOf("a") | 可変リスト |
nums[0], nums.first(), nums.last() | 要素にアクセスする |
nums.getOrNull(9) | 安全なアクセス、範囲外なら null |
items.add("b"), items.remove("a") | 追加 / 削除 |
items[0] = "z" | インデックスで置き換える |
nums.size, nums.isEmpty() | サイズと空かどうか |
x in nums, nums.contains(x) | 所属 |
nums.indexOf(2) | 要素の位置、なければ -1 |
nums.subList(0, 2) | 部分リスト (終端を含まない) |
nums.take(2), nums.drop(1) | 先頭 n 個 / 先頭 n 個を除く全部 |
nums.sorted(), nums.reversed() | ソート済み / 逆順の新しいリスト |
nums.sum(), nums.average(), nums.maxOrNull() | 集計 |
nums.joinToString(", ") | 1つの文字列に結合する |
Pair(1, "a"), 1 to "a", Triple(1, 2, 3) | 小さな固定長タプル |
マップとセット
| 構文 | 意味 |
|---|
val m = mapOf("a" to 1, "b" to 2) | 読み取り専用マップ |
val mm = mutableMapOf<String, Int>() | 可変マップ |
m["a"] | 検索 (なければ null) |
m.getOrDefault("z", 0) | 代替値付きの検索 |
mm["c"] = 3 | 挿入または更新 |
for ((k, v) in m) | 分解宣言でエントリを反復する |
m.keys, m.values | キー / 値のコレクション |
"a" in m | キーの存在 |
val s = setOf(1, 2, 2) | 一意な値のセット ({1, 2}) |
mutableSetOf<Int>() | 可変セット |
コレクション操作 (ラムダ)
| 構文 | 意味 |
|---|
list.map { it * 2 } | 各要素を変換する |
list.filter { it > 2 } | 条件に合う要素だけ残す |
list.forEach { println(it) } | 各要素に対して処理する |
list.any { it > 2 }, list.all { it > 0 } | いずれか / すべての要素が条件を満たすか |
list.count { it % 2 == 0 } | 一致数を数える |
list.find { it > 2 } | 最初の一致または null |
list.sortedBy { it.length } | キーでソートする |
list.groupBy { it.first() } | Map にグループ化する |
list.distinct() | 重複を取り除く |
list.fold(0) { acc, x -> acc + x } | 初期値付きで畳み込む |
list.zip(other) | 2つのリストをペアにする |
list.flatMap { it.toList() } | 変換してから平坦化する |
クラスとデータクラス
| 構文 | 意味 |
|---|
class User(val name: String, var age: Int) | プライマリコンストラクタとプロパティを持つクラス |
val u = User("Ada", 36) | インスタンスを生成する (new 不要) |
u.name, u.age = 37 | プロパティの読み書き |
data class Point(val x: Int, val y: Int) | equals, hashCode, toString, copy が自動生成 |
p.copy(y = 5) | 一部のプロパティを変えてコピー |
val (x, y) = p | 分解宣言 |
open class Base, class Sub : Base() | 継承 (クラスはデフォルトで final) |
override fun toString() = "..." | メンバをオーバーライドする |
object Config { val debug = true } | シングルトン |
companion object { fun create() = User("", 0) } | 静的メンバ相当 |
enum class Color { RED, GREEN } | 列挙型 |
sealed class Result | 制限されたクラス階層、when で網羅的 |
interface Shape { fun area(): Double } | インターフェース |
エラー処理
| 構文 | 意味 |
|---|
try { ... } catch (e: Exception) { ... } | 例外を捕捉する |
try { ... } finally { ... } | 必ず後処理を実行する |
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 } | 式としての try |
throw IllegalArgumentException("bad") | 例外を投げる |
require(x > 0) { "x must be positive" } | 引数チェック (IllegalArgumentException を投げる) |
check(ready) { "not ready" } | 状態チェック (IllegalStateException を投げる) |
s.toIntOrNull() | 例外の代わりに null を返す |
runCatching { risky() }.getOrDefault(0) | 呼び出しを Result で包む |
スコープ関数
ブロック内でオブジェクトを扱うための5つの小さなヘルパー。
| 構文 | 意味 |
|---|
x.let { it + 1 } | it がオブジェクト、ブロックの結果を返す |
x.run { this + 1 } | this がオブジェクト、ブロックの結果を返す |
x.apply { field = 1 } | this がオブジェクト、オブジェクト自身を返す |
x.also { println(it) } | it がオブジェクト、オブジェクト自身を返す |
with(x) { field } | 拡張関数ではない。this は x、ブロックの結果を返す |
x?.let { ... } | 慣用的な null チェック + 利用 |
探している Kotlin の構文をすべて1ページに。この Kotlin チートシートは、Android と現代の JVM の多くを支える言語のクイックリファレンスです。変数の宣言、null の安全な扱い、when による分岐、範囲のループ、関数の記述、リストとマップの操作をまとめました。
ここにあるのはすべて標準の Kotlin で、JVM でも Android でも Kotlin Multiplatform でも同じように動きます。必要な部分をコピーするか、Kotlin プレイグラウンドでそのまま試してください。スニペットを貼り付けて Run を押せば、ブラウザで出力を確認できます。