インデックスとInvoke
get、set、invokeを学びます
「インデックスとInvoke」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
インデックス演算子
operator fun get を定義すると、obj[i] のような角かっこ構文で読み取れます。
class Row(val cells: List<String>) {
operator fun get(i: Int) = cells[i]
}
fun main() {
val r = Row(listOf("a", "b", "c"))
println(r[1])
}set による書き込み
operator fun set によって、obj[i] = value のように代入できます。最後のパラメーターが値になります。
class Grid {
private val data = IntArray(3)
operator fun get(i: Int) = data[i]
operator fun set(i: Int, value: Int) { data[i] = value }
}
fun main() {
val g = Grid()
g[0] = 42
println(g[0])
}複数引数のインデックスアクセス
get と set は複数のインデックスを受け取れるため、行列に最適です。
class Matrix {
private val d = Array(2) { IntArray(2) }
operator fun get(r: Int, c: Int) = d[r][c]
operator fun set(r: Int, c: Int, v: Int) { d[r][c] = v }
}
fun main() {
val m = Matrix()
m[1, 1] = 9
println(m[1, 1])
}Int 以外のキーによるインデックスアクセス
インデックスのパラメーターには任意の型を指定できるため、マップのようなアクセスを実現できます。
class Settings {
private val map = mutableMapOf<String, String>()
operator fun get(key: String) = map[key]
operator fun set(key: String, value: String) { map[key] = value }
}
fun main() {
val s = Settings()
s["theme"] = "dark"
println(s["theme"])
}invoke 演算子
operator fun invoke を定義すると、obj() のようにインスタンスを関数として呼び出せます。
class Greeter(val name: String) {
operator fun invoke() = "Hello, $name"
}
fun main() {
val g = Greeter("Sam")
println(g())
}引数を使った invoke
invoke はパラメーターを受け取れるため、オブジェクトをパラメーター付きの関数のように動作させられます。
class Multiplier(val factor: Int) {
operator fun invoke(x: Int) = x * factor
}
fun main() {
val triple = Multiplier(3)
println(triple(5))
}状態を持つ呼び出し可能オブジェクト
オブジェクトが状態を保持するため、invoke によって設定可能な関数のようなオブジェクトを構築できます。
class Accumulator {
var total = 0
operator fun invoke(n: Int) { total += n }
}
fun main() {
val acc = Accumulator()
acc(5)
acc(10)
println(acc.total)
}複数の invoke オーバーロード
パラメーターの異なる複数の invoke オーバーロードを宣言できます。
class Printer {
operator fun invoke(s: String) = println(s)
operator fun invoke(n: Int) = println("num: $n")
}
fun main() {
val p = Printer()
p("hi")
p(7)
}式の中でのインデックスアクセス
インデックスアクセスは、ほかの操作と自然に組み合わせられます。
class Scores(private val list: List<Int>) {
operator fun get(i: Int) = list[i]
}
fun main() {
val s = Scores(listOf(10, 20, 30))
println(s[0] + s[2])
}get と invoke の組み合わせ
型がインデックスアクセスと呼び出しの両方をサポートすると、表現力の高い API を実現できます。
class Lookup(private val data: Map<String, Int>) {
operator fun get(key: String) = data[key]
operator fun invoke() = data.size
}
fun main() {
val l = Lookup(mapOf("a" to 1))
println(l["a"])
println(l())
}標準ライブラリでの利用方法
List の list[i] と Map の map[key] は、まさにこれらの演算子です。独自の型も同じように自然に使えるようにできます。
fun main() {
val list = listOf(1, 2, 3)
val map = mapOf("x" to 9)
println(list[0])
println(map["x"])
}理解度チェック
インデックスアクセスと invoke についての理解度を確認しましょう。
まとめ
インデックスアクセスと invoke について学びました。
getはobj[i]を、setはobj[i] = vを支えます。- インデックス演算子では、複数のキーや Int 以外のキーを使用できます。
invokeを使うと、引数の有無にかかわらず、インスタンスを関数のように呼び出せます。- 標準コレクションは、まさにこれらの演算子を使用しています。
class Box {
private val m = mutableMapOf<String, Int>()
operator fun get(k: String) = m[k]
operator fun set(k: String, v: Int) { m[k] = v }
}
fun main() {
val b = Box()
b["x"] = 5
println(b["x"])
}よくある質問
「インデックスとInvoke」レッスンは無料ですか?
はい。「インデックスとInvoke」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「インデックスとInvoke」で何を学びますか?
get、set、invokeを学びます ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「インデックスとInvoke」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。