はじめに
先日の KotlinConf'23 内の Keynote にて、Kotlin 2.0 以降で複数の待ち望まれた新機能が実装される予定であることがアナウンスされました。
本記事では新機能の1つである Collection Literals について、YouTrack 内の議論を参考にしながら紹介したいと思います。
注意
Collection Literals は検討中の機能であるため、内容が変更される可能性があります。
Collection Literals とは
ざっくり言うと、これまでリストを作成する際は listOf(1, 2, 3)
のように記述していましたが、これが [1, 2, 3]
のように記述できるようになります。また、List だけではなく、Map や Set も同じシンタックスで記述できます。
【Kotlin】
val list = [1, 2, 3] // list literal
val map = ["one": 1, "two": 2, "three": 3] // map literal
val set: Set<Int> = [1, 2, 3] // creates a Set<Int>
Collection Literals の検討背景
Collection Literals は Kotlin コミュニティにおいて多くの関心を集めていました。Collection Literals は Python、JavaScript、Swift、Rust といった今日使用されているプログラミングに搭載されています。
【Python】
# List
my_list = [1, 2, 3, 4]
# Dictionary
my_dict = {'apple': 1, 'banana': 2, 'orange': 3}
【JavaScript】
// Array
let myArray = [1, 2, 3, 4];
// Object
let myObject = {'apple': 1, 'banana': 2, 'orange': 3};
【Swift】
// Array
let myArray: [Int] = [1, 2, 3, 4]
// Dictionary
let myDict: [String: Int] = ["apple": 1, "banana": 2, "orange": 3]
Collection Literals を導入することは Kotlin にとっても多くの利点があります。
- 簡潔にデータを表現することができる
- 特にデータサイエンス等のデータ重視のアプリケーションで恩恵が大きい
- 各種のコレクション(
listOf
、mapOf
、setOf
など)を共通のシンタックスで記述することができる - 型推論と相性良く共存できる
-
vararg
を使用せずに効率よくコレクションを作成できる
ちなみに C# においても同様の機能が近い将来実装予定となっています。
Collection Literals について詳しく見る
シンタックス
現状は List や Map などコレクションの種類を問わず、大括弧[]
を使用することが検討されています。
val list = [1, 2, 3] // list literal
val map = ["one": 1, "two": 2, "three": 3] // map literal
要件
Collection Literals において検討されている要件は以下の通りです。
- 型が指定されなかった場合はデフォルトで
List<T>
かMap<K, V>
に推論されることval list = [1, 2, 3] // has type of List<Int> val map = ["one": 1, "two": 2, "three": 3] // has type of Map<String, Int>
- 型を指定することでその型に推論されること
val set: Set<Int> = [1, 2, 3] // creates a Set<Int> val map: MutableMap<String, Int> = ["one": 1, "two": 2, "three": 3] // creates a MutableMap
- 右辺で型を指定できること
val array = Array [1, 2, 3] // creates Array<Int>, note that "Int" was inferred here
- typealias とも上手く機能すること
typealias IntList = List<Int> IntList [1, 2, 3] // works
- ユーザーが独自に定義したコレクションにも対応していること
- コンパイラが特別な最適化を行わずとも効率的に設計されていること
懸念点
Collection Literals は汎用性が高いため、例えば以下のような Point
型がコレクション型であるかのように振る舞うことで [1,2]
のように記述することが可能になります。従って、Collection Literals の設計は簡単なオブジェクトリテラルの設計と切り離して考えるべきではないとされています。
data class Point(val x: Int, val y: Int)
fun drawLine(from: Point, to: Point) { ... }
drawLine([1, 2], [3, 4]) // <---
まとめ
Kotlin の Collection Literals について紹介しました。実装されるのは Kotlin 2.0 以降になるので使えるようになるにはまだしばらくかかりそうですが List<T>
や Map<K, V>
を共通のシンタックスで簡潔に記述できるようになることが非常に楽しみです。