Dive into Coding Life

KotlinLearning: 03-1 関数

17/01/2021

関数とは

関数とは特定の処理を完了することができるコードの再利用可能なブロックです。
プログラムは基本的に関数で作成されています。
小さな関数を複数組み合わせることによって、より複雑な処理を実行します。
関数を使う利点としては、

  • 処理を人間から見て意味のある単位でまとめられる
  • 再利用を可能にする
  • 全体のコード量を減らすことができる

などが挙げられます。

関数の構造

Kotlinの関数は、fun キーワードに続けて関数名を指定します。
次に関数が引数として取る関数パラメーターがあればそれを定義し、戻り値として出力する型を宣言します。
関数本文では関数が呼び出された際に実行する式を定義します。

private fun coffeeTaste(sugar: Int): String {
    if (sugar < 1) {
        return "bitter"
    } else {
        return "sweet"
    }
}

private fun coffeeTaste(sugar: Int): String
が関数の定義部で5つの要素からなっています。

private : 可視性修飾子
fun : 関数宣言キーワード
coffeeTaste: 関数名
sugar: Int : 引数(関数パラメーター)
String: 戻り値の型

関数を呼び出すには関数名coffeeTasteを使用し、その後ろにInt型の引数を指定します。
関数の実行結果としてString型の値が戻されますので、適宜変数などで受け取ります。

val taste= coffeeTaste(3);

関数は以下のようにif/else式の実行結果を直接戻り値とすることもできます。

private fun coffeeTaste(sugar: Int): String {
    return if (sugar < 1) {
        "bitter"
    } else {
        "sweet"
    }
}

また、return文を省略し、直接戻り値として演算子に置き換えることもできます。

private fun coffeeTaste(sugar: Int): String = if (sugar < 1) {
    "bitter"
} else {
    "sweet"
}

可視性修飾子

関数の可視性はデフォルトでpublicです。
可視性修飾子を明示的に指定しない限り、他のすべての関数から呼び出すことが可能です。

  • public
  • private
  • protected
  • internal

関数名

関数宣言キーワードと関数名を使用して関数名宣言を完成させます。
一般的に関数名はローワーキャメルケースを使います。
fun coffeeTaste()

引数(関数パラメーター)

一般的には引数と呼ばれますが、正確には仮引数名と型を指定した関数パラメーターと呼ばれます。
引数という語も日本語ではあまり分けて考えませんが、外部から渡され関数内で使われる引数のことを仮引数(parameter)、実際に外部から関数呼び出し時に渡す引数を実引数(argument)と呼び分けて考えます。
渡された実引数は関数内で変更することはできません。

名前付き引数

Kotlinでは関数呼び出し時に渡す引数を仮引数名を使って指定することができます。
名前付き引数を使用する場合、順序は問われません。
ただし混乱を防ぐために全ての引数を名前付きで呼ぶことが推奨されています。

private fun brewSweetCoffeeWithMilk(sugar: Int = 2, milk: Int = 100) {
    println("this coffee use $sugar Spoonful of Sugar and $milk Cc of Milk")
}

brewSweetCoffeeWithMilk(milk = 150, sugar = 0) //全ての引数を名前付きで呼ぶ方が意図が明確
brewSweetCoffeeWithMilk(0, milk = 150) //引数の順序を守れば実行は可能
// brewSweetCoffeeWithMilk(milk = 150, 0) //実行不可(引数の順序を変えた場合は名前付きで呼ぶ必要がある)

デフォルト引数

ちなみに関数パラメーターはデフォルト値を指定することができます。
仮引数にデフォルト値を指定することによりオーバーロードメソッドを複数書く必要がなくなり、またデフォルトの値が明示的でわかりやすくなります。
名前付き引数と組み合わせて使用すると任意の順序で任意の引数を設定できます。
Javaから呼び出す場合はデフォルト引数は使用できず、全ての引数を指定する必要があります。
その際@JvmOverloadsアノテーションを関数につけると自動的に引数を後ろから1つずつ減らしたオーバーロードメソッドを生成するので、全ての引数を指定せずに済ますことができるようになります。

private fun brewSweetCoffee(sugar: Int = 2) {
    println("this coffee use $sugar Spoonful of Sugar")
}

戻り値の型

関数の定義部の最後の要素は戻り値の型です。
関数が処理を完了すると、関数は戻り値として特定の型のデータを返します。
戻り値の型はこの特定の型を規定します。

戻り値がない場合は暗黙的にUnit型の戻り値が返るようになっています。