はじめに
Kotlinをまったく知らないチームメンバーでも、文法の “基礎の基礎” を理解し、
Kotlin Multiplatform(KMP) 実装の第一歩を踏み出せるようにこの記事を作成しました。
Swift経験者向けに、Swiftならこう書くよ!という比較も交えて進めていきます。
Kotlinは触ったことがない、
または入門書レベルを一度読んだだけの方、向けです。
ゴール
- Kotlinの基本文法を手を動かしながら学ぶ
- KMPプロジェクトを作るための土台知識を得る
文字出力
書き方は、ほぼ同じ。
Kotlin
println("Hello, Kotlin!")
Swift
print("Hello, Swift!")
val と var
varは共通でvalの役割がswiftではletになる。
Kotlin
val x: Int = 10 // 不変
var y = 5 // 可変、型推論
y = 20 // 再代入できる
Swift
let x: Int = 10 // 不変
var y = 5 // 可変、型推論
y = 20 // 再代入できる
Null
KotlinとSwiftのどちらも「nullを許すかどうかを明示的に書く」という仕組みがある。
nullを許す型は、型の後に?をつけて書く。
Kotlin
val nonNullable: String = "Hello"
// nonNullable = null // コンパイルエラー!
val nullable: String? = "Hello"
nullable = null // OK
Swift
let nonNullable: String = "Hello"
// nonNullable = nil // コンパイルエラー!
var nullable: String? = "Hello"
nullable = nil // OK
Safe Call Operator(?.)
オブジェクトがnullの場合は
処理をスキップし、nullを返す。
Swiftも同様。
Kotlin
val name: String? = "Kotlin"
val length = name?.length
println(length) // => 6
val name2: String? = null
println(name2?.length) // => null
Swift
let name: String? = "Swift"
let length = name?.count
print(length)
参考:
https://kotlinlang.org/docs/null-safety.html#
Elvis operator(?:)
?: の左側がnullなら"ゲスト"を返す。
これでnullチェック + 代替処理が可能。
Swiftでは??
が同じ役割。
nil-coalescing operatorと呼ぶ。
Kotlin
val name: String? = null
val displayName = name ?: "ゲスト"
println(displayName) // => ゲスト
Swift
let name: String? = nil
let displayName = name ?? "ゲスト"
print(displayName) // => ゲスト
参考:
https://kotlinlang.org/docs/null-safety.html#elvis-operator
制御構文
if
Kotlinのifは式なので、そのまま変数に入れられます。
Swiftは三項演算子が近しいです。
Kotlin
val max = if (x > y) x else y
Swift
let max = (x > y) ? x : y
when
値に応じた処理の分岐をきれいに書ける。
式としても使えるので、if-elseよりスッキリ書ける場面が多い。
下記では、when(色)で評価したい値を渡している。
-> の左がマッチする値、右が実行する処理。
elseはswitchのどれにも一致しないときの処理のdefaultに相当する。
Swiftはswitch
が近しいです。
Kotlin
val color = "blue"
when (color) {
"red" -> println("赤です")
"blue" -> println("青です")
"green" -> println("緑です")
else -> println("未定義の色です")
}
Swift
let color = "blue"
switch color {
case "red":
print("赤です")
case "blue":
print("青です")
case "green":
print("緑です")
default:
print("未定義の色です")
}
関数
下記はsum関数でaとbに引数で数を入れて足した数が返ってくる関数。
書き方としては()の後ろに:をつけて型を指定する。
swiftとは引数や戻り値の書き方がやや異なるが概念は同じ。
Kotlin
fun sum(a: Int, b: Int): Int {
return a + b
}
Swift
func sum(_ a: Int, _ b: Int) -> Int {
return a + b
}
補足
デフォルト引数
引数を指定しなかった場合、name: String = "World"とデフォルト値を設定しているため
Hello, World
と表示される。
引数を指定すると、その引数を使った文字列が返ってくる。
Kotlin
fun greet(name: String = "World") = println("Hello, $name")
greet() // Hello, World
greet("Kotlin") // Hello, Kotlin
コレクション(List/Mapなど)
Kotlinではコレクションを使うのが便利。
基本はJavaに似ているが、Kotlinならではの便利な関数や型の違いがある。
List(リスト)
順番があるデータの集まりで配列のようなもの。
listOf()
は 読み取り専用(immutable)で、fruits[0] でアクセスできる。
要素の追加・削除はできない。
swiftは書き方が違うだけで動きは同じ。
Kotlin
val fruits = listOf("Apple", "Banana", "Cherry")
println(fruits[1]) // => Banana
Swift
let fruits = ["Apple", "Banana", "Cherry"]
print(fruits[1]) // => Banana
追加、削除を行いたいときはMutableListを使用する。
add(), removeAt()などのメソッドが使える。
MutableList
Kotlin
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)
numbers.removeAt(0)
println(numbers) // => [2, 3, 4]
Swift
var numbers = [1, 2, 3]
numbers.append(4)
numbers.remove(at: 0)
print(numbers)
Map(マップ)
キーと値のセットで辞書のようなもの。
mapOf()
も読み取り専用で"France"というキーに対応する値は "Paris"
Swiftでは辞書は[Key: Value]という構文になる。
Kotlin
val capitals = mapOf(
"Japan" to "Tokyo",
"France" to "Paris",
"USA" to "Washington"
)
println(capitals["France"]) // => Paris
Swift
let capitals = [
"Japan": "Tokyo",
"France": "Paris",
"USA": "Washington"
]
print(capitals["France"] ?? "")
補足: Listと同じくMapにもMutableMapがある。
forEach
forEachは、コレクションのすべての要素に対して、順番に処理を実行する関数。
Kotlinはit
でSwiftは$0
の違いがある。
Kotlin
val fruits = listOf("Apple", "Banana", "Cherry")
fruits.forEach { fruit ->
println("果物: $fruit")
}
// =>
果物: Apple
果物: Banana
果物: Cherry
itを使えば { println(it) } のようにも書ける。
出力結果は上記と同じ
fruits.forEach {
println("果物: $it")
}
Swift
let fruits = ["Apple", "Banana", "Cherry"]
fruits.forEach {
print("果物: \($0)")
}
filter
filterは、リストなどのコレクションから「条件に合うものだけ」を抜き出して新しいリストを作る関数。
書き方は、filter { 条件 } で、itはリストの中の1つ1つの要素。
length > 5のように、条件式がtrueになる要素だけが結果に含まれる。
ただし、元のリストは変わらない(イミュータブル)。
swiftとほぼ同じ構文になる。
Kotlin
val fruits = listOf("Apple", "Banana", "Cherry", "Fig")
val longFruits = fruits.filter { it.length > 5 }
println(longFruits)
// => [Banana, Cherry]
Swift
let fruits = ["Apple", "Banana", "Cherry", "Fig"]
let longFruits = fruits.filter { $0.count > 5 }
print(longFruits)
ちょっと応用編
拡張関数
Kotlinの特徴的な機能のひとつが拡張関数。
すでにあるクラスに、あとから新しい関数を追加できる機能。
しかも、元のクラスを継承したり変更したりする必要はなし。
基本の書き方
fun 型名.関数名(引数): 戻り値 {
// 処理内容
}
例 Stringにgreetという関数を追加
fun String.greet(): String {
return "Hello, $this!"
}
val name = "Kotlin"
println(name.greet()) // => Hello, Kotlin!
String.greet() で、元からあった関数のように呼び出せる。
thisは、拡張対象(この場合は "Kotlin")を指す。
拡張関数は「見かけ上そのクラスのメンバーのように振る舞う」だけで、実際にクラスに組み込まれるわけではない。
参考:
https://kotlinlang.org/docs/extensions.html#extension-functions
まとめ
- Kotlinは型安全で、nullの扱いが厳密
- 変数定義(val/var)・関数・制御構文など、Java/Swift経験者にも馴染みやすい構文
- コレクション操作(forEach/filterなど)がシンプルで表現力が高い
この記事では、Kotlin を初めて触る人が文法の基礎を理解し、Kotlin Multiplatform(KMP)に入っていくための「基礎」をまとめました。
まずは文法を手を動かして試しながら、徐々にKMPプロジェクトに進んでいきましょう!