プログラマー向け Kotlin ブートキャンプ 3: 関数

この Codelab は、プログラマー向け Kotlin ブートキャンプ コースの一部です。このコースを最大限に活用するには、Codelab を順番に進めることをおすすめします。理解度によっては、特定のセクションの概要を読むだけで済む場合があります。このコースは、オブジェクト指向言語の知識があり、Kotlin を学習したいプログラマーを対象としています。

はじめに

この Codelab では、Kotlin プログラムを作成し、パラメータ、フィルタ、ラムダ、コンパクト関数のデフォルト値など、Kotlin の関数について学習します。

このコースのレッスンは、1 つのサンプルアプリを作成するのではなく、知識を深めるように設計されています。また、各レッスンは半独立しているため、よく知っているセクションは読み飛ばすことができます。これらの例を関連付けるため、多くは水族館をテーマにしています。水族館の物語の全体像を確認したい場合は、Udacity の Kotlin ブートキャンプ(プログラマー向け)コースをご覧ください。

前提となる知識

  • 最新のオブジェクト指向の静的型付けプログラミング言語の基礎
  • 少なくとも 1 つの言語でクラス、メソッド、例外処理を使用してプログラミングする方法
  • IntelliJ IDEA で Kotlin の REPL(Read-Eval-Print Loop)を使用する方法
  • Kotlin の基本(型、演算子、ループなど)

この Codelab は、オブジェクト指向言語の知識があり、Kotlin について詳しく学びたいプログラマーを対象としています。

学習内容

  • IntelliJ IDEA で main() 関数と引数を使ってプログラムを作成する方法
  • デフォルト値とコンパクト関数を使用する方法
  • リストにフィルタを適用する方法
  • 基本的なラムダ式と高階関数を作成する方法

演習内容

  • REPL を使用してコードを試してみます。
  • IntelliJ IDEA を使用して基本的な Kotlin プログラムを作成します。

このタスクでは、Kotlin プログラムを作成し、main() 関数と、コマンドラインからプログラムに引数を渡す方法について学習します。

前の Codelab で REPL に入力した printHello() 関数を思い出してください。

fun printHello() {
    println ("Hello World")
}

printHello()
⇒ Hello World

関数は、fun キーワードの後に続く関数名を使用して定義します。他のプログラミング言語と同様に、括弧 () は関数引数(存在する場合)用です。中かっこ {} は、関数のコードを囲みます。この関数は何も返さないため、戻り値の型はありません。

ステップ 1: Kotlin ファイルを作成する

  1. IntelliJ IDEA を開きます。
  2. IntelliJ IDEA の左側の [Project] ペインには、プロジェクトのファイルとフォルダのリストが表示されます。[Hello Kotlin] の下にある src フォルダを見つけて右クリックします。(前の Codelab で Hello Kotlin プロジェクトを作成済みであるはずです)。
  3. [New] > [Kotlin File / Class] を選択します。
  4. [Kind] は [File] のままにして、ファイルに「Hello」という名前を付けます。
  5. [OK] をクリックします。

src フォルダに Hello.kt というファイルが作成されます。

ステップ 2: コードを追加してプログラムを実行する

  1. 他の言語と同様に、Kotlin の main() 関数は実行のエントリ ポイントを指定します。コマンドライン引数は文字列の配列として渡されます。

    Hello.kt ファイルに次のコードを入力するか貼り付けます。
fun main(args: Array<String>) {
    println("Hello, world!")
}

前の printHello() 関数と同様に、この関数には return ステートメントがありません。Kotlin のすべての関数は、明示的に指定されていない場合でも、何かを返します。したがって、このような main() 関数は、Kotlin で値がないことを示す kotlin.Unit 型を返します。

  1. プログラムを実行するには、main() 関数の左側にある緑色の三角形をクリックします。メニューから [Run 'HelloKt'] を選択します。
  2. IntelliJ IDEA がプログラムをコンパイルして実行します。結果は、次の図に示すように、下部のログペインに表示されます。

ステップ 3: main() に引数を渡す

プログラムをコマンドラインではなく IntelliJ IDEA から実行しているため、プログラムの引数を少し異なる方法で指定する必要があります。

  1. [Run] > [Edit Configurations] の順に選択します。[Run/Debug Configurations] ウィンドウが開きます。
  2. [プログラム引数] フィールドに「Kotlin!」と入力します。
  3. [OK] をクリックします。

ステップ 4: 文字列テンプレートを使用するようにコードを変更する

文字列テンプレートは、変数または式を文字列に挿入します。$ は、文字列の一部が変数または式になることを指定します。中かっこ {} は、式(存在する場合)を囲みます。

  1. Hello.kt で、挨拶メッセージを変更して、"world" ではなく、プログラムに渡された最初の引数 args[0] を使用するようにします。
fun main(args: Array<String>) {
    println("Hello, ${args[0]}")
}
  1. プログラムを実行すると、指定した引数が出力に含まれます。
⇒ Hello, Kotlin!

このタスクでは、Kotlin のほぼすべてのものに値がある理由と、それがなぜ有用なのかを学習します。

他の言語には、値のないコード行であるステートメントがあります。Kotlin では、ほとんどすべてのものがであり、値(kotlin.Unit であっても)を持ちます。

  1. Hello.kt で、main() にコードを記述して、println()isUnit という変数に割り当てて出力します。(println() は値を返さないため、kotlin.Unit を返します)。
// Will assign kotlin.Unit
val isUnit = println("This is an expression")
println(isUnit)
  1. プログラムを実行します。最初の println() は文字列 "This is an expression" を出力します。2 番目の println() は、最初の println() ステートメントの値(kotlin.Unit)を出力します。
⇒ This is an expression
kotlin.Unit
  1. temperature という val を宣言し、10 に初期化します。
  2. 次のコードに示すように、isHot という別の val を宣言し、if/else ステートメントの戻り値を isHot に割り当てます。式であるため、if 式の値をすぐに使用できます。
val temperature = 10
val isHot = if (temperature > 50) true else false
println(isHot)
⇒ false
  1. 文字列テンプレートで式の値を使用します。温度を確認して魚が安全かどうか、または熱すぎないかどうかを判断するコードを追加し、プログラムを実行します。
val temperature = 10
val message = "The water temperature is ${ if (temperature > 50) "too warm" else "OK" }."
println(message)
⇒ The water temperature is OK.

このタスクでは、Kotlin の関数と、非常に便利な when 条件式について詳しく学習します。

ステップ 1: 関数を作成する

このステップでは、これまでに学習した内容をまとめ、さまざまな型の関数を作成します。Hello.kt の内容をこの新しいコードに置き換えることができます。

  1. randomDay() を呼び出してランダムな曜日を取得する feedTheFish() という関数を作成します。文字列テンプレートを使用して、その日に食べる魚の food を出力します。今のところ、魚は毎日同じ餌を食べています。
fun feedTheFish() {
    val day = randomDay()
    val food = "pellets"
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}
  1. 配列からランダムな曜日を選択して返す randomDay() 関数を作成します。

nextInt() 関数は整数制限を受け取り、week 配列に一致するように Random() から 0 ~ 6 までの数値を制限します。

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
            "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}
  1. Random() 関数と nextInt() 関数は java.util.* で定義されています。ファイルの先頭に必要な import を追加します。
import java.util.*    // required import
  1. プログラムを実行し、出力を確認します。
⇒ Today is Tuesday and the fish eat pellets

ステップ 2: when 式を使用する

さらに、when 式を使用して、曜日ごとに異なる食べ物を選ぶようにコードを変更します。when ステートメントは他のプログラミング言語の switch に似ていますが、when は各ブランチの末尾で自動的にブレークします。また、列挙型をチェックしている場合は、コードがすべてのブランチをカバーしていることを確認します。

  1. Hello.kt で、fishFood() という関数を追加します。この関数は、曜日を String として受け取り、その日の魚の餌を String として返します。when() を使用して、毎日魚に特定の餌を与えます。プログラムを数回実行して、さまざまな出力を確認します。
fun fishFood (day : String) : String {
    var food = ""
    when (day) {
        "Monday" -> food = "flakes"
        "Tuesday" -> food = "pellets"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Saturday" -> food = "lettuce"
        "Sunday" -> food = "plankton"
    }
    return food
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)

    println ("Today is $day and the fish eat $food")
}
⇒ Today is Thursday and the fish eat granules
  1. else を使用して、when 式にデフォルトの分岐を追加します。テストでは、プログラムでデフォルトが使用されることを確認するために、Tuesday 分岐と Saturday 分岐を削除します。

    デフォルトの分岐があると、food は返される前に値を取得するため、初期化する必要がなくなります。コードで food に文字列を割り当てるのは 1 回だけになったため、var ではなく val を使用して food を宣言できます。
fun fishFood (day : String) : String {
    val food : String
    when (day) {
        "Monday" -> food = "flakes"
        "Wednesday" -> food = "redworms"
        "Thursday" -> food = "granules"
        "Friday" -> food = "mosquitoes"
        "Sunday" -> food = "plankton"
        else -> food = "nothing"
    }
    return food
}
  1. すべての式には値があるため、このコードをもう少し簡潔にすることができます。when 式の値を直接返し、food 変数を削除します。when 式の値は、条件を満たしたブランチの最後の式の値です。
fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

プログラムの最終版は次のようになります。

import java.util.*    // required import

fun randomDay() : String {
    val week = arrayOf ("Monday", "Tuesday", "Wednesday", "Thursday",
        "Friday", "Saturday", "Sunday")
    return week[Random().nextInt(week.size)]
}

fun fishFood (day : String) : String {
    return when (day) {
        "Monday" -> "flakes"
        "Wednesday" -> "redworms"
        "Thursday" -> "granules"
        "Friday" -> "mosquitoes"
        "Sunday" -> "plankton"
        else -> "nothing"
    }
}

fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
}

fun main(args: Array<String>) {
    feedTheFish()
}

このタスクでは、関数とメソッドのデフォルト値について学習します。また、コードを簡潔で読みやすくし、テストのコードパスの数を減らすことができるコンパクト関数についても学習します。コンパクト関数は、単一式関数とも呼ばれます。

ステップ 1: パラメータのデフォルト値を作成する

Kotlin では、パラメータ名で引数を渡すことができます。パラメータのデフォルト値を指定することもできます。呼び出し元から引数が指定されていない場合は、デフォルト値が使用されます。後でメソッド(メンバー関数)を記述するときに、同じメソッドのオーバーロード バージョンを多数記述する必要がなくなります。

  1. Hello.kt で、魚の速度を出力する speed という名前の String パラメータを持つ swim() 関数を記述します。speed パラメータのデフォルト値は "fast" です。
fun swim(speed: String = "fast") {
   println("swimming $speed")
}
  1. main() 関数から swim() 関数を 3 つの方法で呼び出します。まず、デフォルトを使用して関数を呼び出します。次に、関数を呼び出して名前のない speed パラメータを渡し、speed パラメータに名前を付けて関数を呼び出します。
swim()   // uses default speed
swim("slow")   // positional argument
swim(speed="turtle-like")   // named parameter
⇒ swimming fast
swimming slow
swimming turtle-like

ステップ 2: 必須パラメータを追加する

パラメータにデフォルトが指定されていない場合、対応する引数は常に渡す必要があります。

  1. Hello.kt で、daytemperaturedirty レベルの 3 つのパラメータを受け取る shouldChangeWater() 関数を記述します。水換えが必要な場合は true を返します。水換えが必要なのは、日曜日、水温が高すぎる、水が汚すぎる場合です。曜日が必須ですが、デフォルトの温度は 22、デフォルトの汚れレベルは 20 です。

    引数なしの when 式を使用します。これは Kotlin では一連の if/else if チェックとして機能します。
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        temperature > 30 -> true
        dirty > 30 -> true
        day == "Sunday" ->  true
        else -> false
    }
}
  1. feedTheFish() から shouldChangeWater() を呼び出し、日付を指定します。day パラメータにはデフォルトがないため、引数を指定する必要があります。shouldChangeWater() の他の 2 つのパラメータにはデフォルト値があるため、引数を渡す必要はありません。
fun feedTheFish() {
    val day = randomDay()
    val food = fishFood(day)
    println ("Today is $day and the fish eat $food")
    println("Change water: ${shouldChangeWater(day)}")
}
=> Today is Thursday and the fish eat granules
Change water: false

ステップ 3: コンパクトな関数を作成する

前のステップで記述した when 式は、少量のコードに多くのロジックを詰め込んでいます。少し分解したい場合や、チェックする条件が複雑な場合は、名前が適切に付けられたローカル変数を使用できます。Kotlin では、コンパクト関数を使用してこれを行います。

コンパクト関数(単一式関数)は、Kotlin で一般的なパターンです。関数が単一式の結果を返す場合は、= 記号の後に関数の本体を指定し、波かっこ {}return を省略できます。

  1. Hello.kt で、条件をテストするコンパクト関数を追加します。
fun isTooHot(temperature: Int) = temperature > 30

fun isDirty(dirty: Int) = dirty > 30

fun isSunday(day: String) = day == "Sunday"
  1. 新しい関数を呼び出すように shouldChangeWater() を変更します。
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20): Boolean {
    return when {
        isTooHot(temperature) -> true
        isDirty(dirty) -> true
        isSunday(day) -> true
        else  -> false
    }
}
  1. プログラムを実行します。shouldChangeWater() を使用した println() の出力は、コンパクト関数を使用する前に戻す必要があります。

デフォルト値

パラメータのデフォルト値は値である必要はありません。次の部分的なサンプルに示すように、別の関数にすることもできます。

fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = getDirtySensorReading()): Boolean {
    ...

このタスクでは、Kotlin のフィルタについて少し学習します。フィルタは、条件に基づいてリストの一部を取得するのに便利な方法です。

ステップ 1: フィルタを作成する

  1. Hello.kt で、listOf() を使用して最上位レベルで水族館の装飾のリストを定義します。Hello.kt の内容を置き換えることができます。
val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
  1. 文字「p」で始まる装飾のみを出力する行を含む新しい main() 関数を作成します。フィルタ条件のコードは波かっこ {} で囲まれており、it はフィルタがループ処理を行う際の各項目を指します。式が true を返した場合、アイテムは含まれます。
fun main() {
    println( decorations.filter {it[0] == 'p'})
}
  1. プログラムを実行すると、[実行] ウィンドウに次の出力が表示されます。
⇒ [pagoda, plastic plant]

ステップ 2: eager フィルタと lazy フィルタを比較する

他の言語のフィルタに慣れている方は、Kotlin のフィルタが eagerlazy か疑問に思うかもしれません。結果リストはすぐに作成されますか、それともリストにアクセスしたときに作成されますか?Kotlin では、必要な方法で実行できます。デフォルトでは、filter は eager で、フィルタを使用するたびにリストが作成されます。

フィルタを遅延させるには、Sequence を使用します。これは、先頭から末尾まで一度に 1 つのアイテムしか参照できないコレクションです。都合の良いことに、これは遅延フィルタが必要とする API とまったく同じです。

  1. Hello.kt で、コードを変更して、フィルタされたリストを eager という変数に割り当ててから、出力します。
fun main() {
    val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

    // eager, creates a new list
    val eager = decorations.filter { it [0] == 'p' }
    println("eager: " + eager)
  1. そのコードの下で、asSequence() を含む Sequence を使用してフィルタを評価します。シーケンスを filtered という変数に割り当てて、出力します。
   // lazy, will wait until asked to evaluate
    val filtered = decorations.asSequence().filter { it[0] == 'p' }
    println("filtered: " + filtered)

フィルタ結果を Sequence として返すと、filtered 変数は新しいリストを保持しません。リスト要素の Sequence と、それらの要素に適用するフィルタの知識を保持します。Sequence の要素にアクセスするたびに、フィルタが適用され、結果が返されます。

  1. toList() を使用してシーケンスを List に変換し、シーケンスの評価を強制します。結果を出力します。
    // force evaluation of the lazy list
    val newList = filtered.toList()
    println("new list: " + newList)
  1. プログラムを実行して出力を確認します。
⇒ eager: [pagoda, plastic plant]
filtered: kotlin.sequences.FilteringSequence@386cc1c4
new list: [pagoda, plastic plant]

Sequence と遅延評価の動作を可視化するには、map() 関数を使用します。map() 関数は、シーケンス内の各要素に対して単純な変換を行います。

  1. 上記の decorations リストを使用して、何も行わず、渡された要素を返すだけの map() を使用して変換を行います。println() を追加して、要素がアクセスされるたびに表示し、シーケンスを lazyMap という変数に割り当てます。
    val lazyMap = decorations.asSequence().map {
        println("access: $it")
        it
    }
  1. lazyMap を出力し、first() を使用して lazyMap の最初の要素を出力し、List に変換された lazyMap を出力します。
    println("lazy: $lazyMap")
    println("-----")
    println("first: ${lazyMap.first()}")
    println("-----")
    println("all: ${lazyMap.toList()}")
  1. プログラムを実行し、出力を確認します。lazyMap を出力すると、Sequence への参照が出力されるだけで、内部の println() は呼び出されません。最初の要素を出力すると、最初の要素のみがアクセスされます。SequenceList に変換すると、すべての要素にアクセスできます。
⇒ lazy: kotlin.sequences.TransformingSequence@5ba23b66
-----
access: rock
first: rock
-----
access: rock
access: pagoda
access: plastic plant
access: alligator
access: flowerpot
all: [rock, pagoda, plastic plant, alligator, flowerpot]
  1. map を適用する前に、元のフィルタを使用して新しい Sequence を作成します。その結果を出力します。
    val lazyMap2 = decorations.asSequence().filter {it[0] == 'p'}.map {
        println("access: $it")
        it
    }
    println("-----")
    println("filtered: ${ lazyMap2.toList() }")
  1. プログラムを実行して、追加された出力を確認します。最初の要素を取得する場合と同様に、内部の println() はアクセスされた要素に対してのみ呼び出されます。
⇒
-----
access: pagoda
access: plastic plant
filtered: [pagoda, plastic plant]

このタスクでは、Kotlin のラムダ式と高階関数について説明します。

ラムダ

Kotlin は、従来の名前付き関数に加えて、ラムダをサポートしています。ラムダは関数を作成する式です。名前付き関数を宣言するのではなく、名前のない関数を宣言します。この機能が有用な理由の一つは、ラムダ式をデータとして渡せるようになったことです。他の言語では、ラムダは匿名関数、関数リテラルなどの名前で呼ばれます。

高階関数

ラムダを別の関数に渡すことで、高階関数を作成できます。前のタスクでは、filter という高階関数を作成しました。次のラムダ式を filter に渡して、チェックする条件としています。
{it[0] == 'p'}

同様に、map は高階関数であり、それに渡したラムダは適用する変換でした。

ステップ 1: ラムダについて学習する

  1. 名前付き関数と同様に、ラムダにはパラメータを指定できます。ラムダの場合、パラメータ(必要に応じて型も)は関数矢印 -> の左側に記述します。実行するコードは、関数矢印の右側に記述します。ラムダが変数に割り当てられると、関数と同じように呼び出すことができます。

    REPL([Tools] > [Kotlin] > [Kotlin REPL])を使用して、次のコードを試してください。
var dirtyLevel = 20
val waterFilter = { dirty : Int -> dirty / 2}
println(waterFilter(dirtyLevel))
⇒ 10

この例では、ラムダは dirty という名前の Int を受け取り、dirty / 2 を返します。(フィルタリングによって汚れが除去されるため)。

  1. Kotlin の関数型の構文は、ラムダの構文と密接に関連しています。この構文を使用すると、関数を保持する変数をクリーンに宣言できます。
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

コードは次のようになっています。

  • waterFilter という変数を作成します。
  • waterFilter は、Int を受け取って Int を返す任意の関数にできます。
  • ラムダを waterFilter に割り当てます。
  • ラムダは、引数 dirty を 2 で割った値を返します。

ラムダ引数の型を指定する必要はなくなりました。型は型推論によって計算されます。

ステップ 2: 高階関数を作成する

これまでのところ、ラムダの例はほとんど関数のように見えます。ラムダの真の力は、高階関数を作成するために使用することにあります。高階関数では、ある関数の引数が別の関数になります。

  1. 高階関数を記述します。基本的な例として、2 つの引数を取る関数を次に示します。最初の引数は整数です。2 番目の引数は、整数を受け取って整数を返す関数です。REPL で試してみましょう。
fun updateDirty(dirty: Int, operation: (Int) -> Int): Int {
   return operation(dirty)
}

コードの本体は、2 番目の引数として渡された関数を呼び出し、最初の引数をその関数に渡します。

  1. この関数を呼び出すには、整数と関数を渡します。
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }
println(updateDirty(30, waterFilter))
⇒ 15

渡す関数はラムダである必要はありません。代わりに、通常の名前付き関数を使用できます。引数を通常の関数として指定するには、:: 演算子を使用します。これにより、Kotlin は関数を呼び出そうとしているのではなく、関数参照を引数として渡していることを認識します。

  1. 通常の名前付き関数を updateDirty() に渡してみてください。
fun increaseDirty( start: Int ) = start + 1

println(updateDirty(15, ::increaseDirty))
⇒ 16
var dirtyLevel = 19;
dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}
println(dirtyLevel)
⇒ 42
  • IntelliJ IDEA で Kotlin ソースファイルを作成するには、Kotlin プロジェクトから始めます。
  • IntelliJ IDEA でプログラムをコンパイルして実行するには、main() 関数の横にある緑色の三角形をクリックします。出力は下のログ ウィンドウに表示されます。
  • IntelliJ IDEA で、[Run] > [Edit Configurations]main() 関数に渡すコマンドライン引数を指定します。
  • Kotlin では、ほとんどすべてのものに値があります。この事実を利用して、if または when の値を式または戻り値として使用することで、コードをより簡潔にすることができます。
  • デフォルト引数を使用すると、関数やメソッドの複数のバージョンを用意する必要がなくなります。例:
    fun swim(speed: String = "fast") { ... }
  • コンパクト関数(単一式関数)を使用すると、コードの可読性を高めることができます。例:
    fun isTooHot(temperature: Int) = temperature > 30
  • ラムダ式を使用するフィルタの基本について説明しました。例:
    val beginsWithP = decorations.filter { it [0] == 'p' }
  • ラムダ式は、名前のない関数を作成する式です。ラムダ式は、中かっこ {} の間に定義します。
  • 高階関数では、ラムダ式などの関数をデータとして別の関数に渡します。例:
    dirtyLevel = updateDirty(dirtyLevel) { dirtyLevel -> dirtyLevel + 23}

このレッスンには多くの内容が含まれています。特にラムダを初めて使用する場合は、そう感じるでしょう。後のレッスンで、ラムダ式と高階関数について再度説明します。

Kotlin ドキュメント

このコースのトピックについてさらに詳しい情報が必要な場合や、行き詰まった場合は、https://kotlinlang.org を参照することをおすすめします。

Kotlin のチュートリアル

https://try.kotlinlang.org には、Kotlin Koans という豊富なチュートリアル、ウェブベースのインタープリタ、例を含む完全なリファレンス ドキュメントが用意されています。

Udacity コース

このトピックに関する Udacity コースについては、プログラマー向け Kotlin ブートキャンプをご覧ください。

IntelliJ IDEA

IntelliJ IDEA のドキュメントは、JetBrains のウェブサイトで確認できます。

このセクションでは、インストラクター主導のコースの一環として、この Codelab に取り組んでいる生徒向けに考えられる宿題をいくつか示します。インストラクターは、以下のようなことを行えます。

  • 必要に応じて宿題を与える
  • 宿題の提出方法を生徒に伝える
  • 宿題を採点する

インストラクターは、これらの提案を必要なだけ使用し、必要に応じて他の宿題も自由に与えることができます。

この Codelab に独力で取り組む場合は、これらの宿題を自由に使用して知識をテストしてください。

以下の質問に回答してください

問題 1

contains(element: String) 関数は、呼び出し元の文字列に文字列 element が含まれている場合は true を返します。次のコードの出力は何ですか?

val decorations = listOf ("rock", "pagoda", "plastic plant", "alligator", "flowerpot")

println(decorations.filter {it.contains('p')})

[pagoda, plastic, plant]

[pagoda, plastic plant]

[pagoda, plastic plant, flowerpot]

[rock, alligator]

問題 2

次の関数定義では、どのパラメータが必要ですか?
fun shouldChangeWater (day: String, temperature: Int = 22, dirty: Int = 20, numDecorations: Int = 0): Boolean {...}

numDecorations

dirty

day

temperature

問題 3

通常の名前付き関数(呼び出しの結果ではない)を別の関数に渡すことができます。increaseDirty( start: Int ) = start + 1updateDirty(dirty: Int, operation: (Int) -> Int) に渡すにはどうすればよいですか?

updateDirty(15, &increaseDirty())

updateDirty(15, increaseDirty())

updateDirty(15, ("increaseDirty()"))

updateDirty(15, ::increaseDirty)

次のレッスンに進みます。4. クラスとオブジェクト

他の Codelab へのリンクを含むコースの概要については、「プログラマー向け Kotlin ブートキャンプ: コースへようこそ」をご覧ください。