使い分け
トレードオフを学びます
「使い分け」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
2つのツール、それぞれの役割
インフィックス関数は可読性のためのものであり、tailrec関数は安全で効率的な再帰のためのものです。両者は無関係な問題を解決します。
infix fun Int.add(o: Int) = this + o
tailrec fun sum(n: Int, acc: Int = 0): Int =
if (n == 0) acc else sum(n - 1, acc + n)
fun main() {
println(2 add 3)
println(sum(10))
}流れるような API にはインフィックスを選ぶ
ドットやかっこを省略したほうが呼び出しが読みやすくなる場合、特に DSL や Pair の構築では、インフィックスを使用してください。
fun main() {
val pair = "id" to 100
println(pair)
}深い再帰には tailrec を選ぶ
再帰アルゴリズムがスタックを使い果たすほど深く再帰する可能性がある場合は、tailrec を使用してください。
tailrec fun count(n: Int, acc: Int = 0): Int =
if (n == 0) acc else count(n - 1, acc + 1)
fun main() {
println(count(50000))
}インフィックスのトレードオフ
インフィックス関数は句読点を省略するため、慣れていない読者には分かりにくくなり、優先順位も複雑になります。明確に役立つ場合にのみ使用してください。
infix fun Int.scaledBy(f: Int) = this * f
fun main() {
println(5 scaledBy 3)
}tailrec のトレードオフ
コードを末尾再帰にするにはアキュムレーターが必要になることが多く、通常のループよりも直接的でないと感じられる場合があります。表現力とシンプルさのバランスを考えてください。
tailrec fun product(n: Int, acc: Long = 1): Long =
if (n <= 1) acc else product(n - 1, acc * n)
fun main() {
println(product(6))
}ループのほうがシンプルな場合
通常の for ループや while ループのほうが末尾再帰より明確なら、ループを優先してください。再帰はツールであり、必須条件ではありません。
fun sumLoop(n: Int): Int {
var total = 0
for (i in 1..n) total += i
return total
}
fun main() {
println(sumLoop(10))
}名前付き呼び出しのほうが明確な場合
インフィックスの名前が明らかに二項関係を表していない場合は、通常のメソッド呼び出しのほうが意図を明確に伝えられます。
data class Temp(val c: Int) {
fun isWarmerThan(o: Temp) = c > o.c
}
fun main() {
println(Temp(30).isWarmerThan(Temp(20)))
}両方の組み合わせ
この2つの機能は独立しています。1つのプログラムで、読みやすい呼び出しにはインフィックスを、安全な再帰には tailrec を使用できます。
infix fun Int.upto(n: Int) = (this..n).toList()
tailrec fun last(list: List<Int>): Int =
if (list.size == 1) list[0] else last(list.drop(1))
fun main() {
println(last(1 upto 5))
}可読性チェックリスト
次の点を確認してください。インフィックスによって、初心者にも呼び出しが分かりやすくなりますか。tailrec によって、現実的なオーバーフローのリスクを防げますか。どちらも当てはまらない場合は、通常の関数とループを優先してください。
fun main() {
val r = (1..5).sum()
println(r)
}パフォーマンスに関する注意
tailrec は、スタック領域を一定量に保ちながら、ループに近いパフォーマンスを実現します。インフィックスには実行時コストがなく、純粋に構文上の機能です。
tailrec fun pow(base: Int, exp: Int, acc: Long = 1): Long =
if (exp == 0) acc else pow(base, exp - 1, acc * base)
fun main() {
println(pow(2, 10))
}判断のまとめ
インフィックスは、流れるように記述できる1引数の二項演算風の呼び出しに適しています。tailrec は、安全に拡張できる必要がある再帰に適しています。どちらも標準的に使うものではなく、意図的に選択する機能です。
infix fun String.joinWith(o: String) = "$this-$o"
fun main() {
println("a" joinWith "b")
}理解度チェック
それぞれの機能をいつ使用するかについての理解度を確認しましょう。
まとめ
それぞれを使用する場面について学びました。
- 流れるように記述できる読みやすい二項演算風の呼び出しや DSL には、
infixを使用します。 - スタックオーバーフローを起こさずに拡張する必要がある再帰には、
tailrecを使用します。 - 通常のループや名前付き関数のほうが明確な場合は、そちらを優先します。
- この2つの機能は独立しており、組み合わせることもできます。
infix fun Int.by(o: Int) = this * o
tailrec fun dec(n: Int): Int = if (n == 0) 0 else dec(n - 1)
fun main() {
println(3 by 4)
println(dec(1000))
}よくある質問
「使い分け」レッスンは無料ですか?
はい。「使い分け」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「使い分け」で何を学びますか?
トレードオフを学びます ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「使い分け」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。