Dive into Coding Life

KotlinLearning: 03-3 関数

単一式関数 Single-expression functions

式ステートメントが1つしかない場合、または評価ステートメントが1行しかない場合、その関数を単一式関数と呼びます。

fun isValid(inputName: String): Boolean {
    return inputName.isNotEmpty()
}

Kotlinでは単一式関数の場合、

  • 戻り値の型
  • 中カッコ
  • returnステートメント

をすべて省略できます。

fun isValid(inputName: String) = inputName.isNotEmpty()

Unit関数

関数はその定義として戻り値があることを規定していますが、全ての関数に戻り値が必要なわけではありません。
一部の関数は変数の状態を変更したり、システム出力を生成する他の関数を呼び出したり、関数にも様々な役割があります。
Kotlinではこのような戻り値を返す必要がない関数をUnit関数と呼びます。

Unit関数の戻り値はUnit型になります。
Javaのvoidは戻り値がないことを示していますが、KotlinのUnitはUnit型のオブジェクトを返します。

Unit型

関数が値を返す必要がない場合、デフォルトの戻り値はUnit型です。

fun setColor(color: Int): Unit {
}

Unit型の戻り値は省略可能です。

fun setColor(color: Int) {
}

Nothing型関数

Unit型と同様にNothing型の関数も何も返さないことを意味します。
コンパイラにとってはNothing型は関数を正常に実行できないというマーカーを意味しています。
例外がスローされる場合や、何らかの理由で関数の呼び出し元に戻ることができない場合、Nothing型を使用します。

例えばTODO関数は正常に実行されることを期待せず例外を発生させNothing型を返します。

fun shouldReturnAString(): String {
    TODO("implement the string building functionality here to return a string")
}

Nothing型

関数がNothing型を返す場合、その関数は実行されないことを意味します。
例えばTODO()関数は実行される例外をスローするのでNothing型を返します。

public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")

関数のオーバーロード

同名の関数の実装はその引数に応じて複数あり得ます。
この機能はオーバーロードと呼ばれています。

Kotlinではデフォルトの引数を割り当てることによりオーバーロードを実装する数を減らすことができます。

fun sum(a: Double, b: Double): Double {
    return a + b
}

fun sum(a: Double, b: Double, c: Double): Double {
    return a + b + c
}

これは可変長引数をとるvarargを用い、以下のように書き換えることができます。

fun sum(vararg a: Double): Double {
    return a.sum()
}

逆引用符で囲まれた関数

Kotlinでは特殊文字やスペースを使った特別な名前の関数を定義することができます。
これらの関数は定義時、呼び出し時、共に逆引用符(バッククォート)で囲む必要があります。

fun `**~this is a method!~**`() {
    // このメソッドは次のように呼び出します
    // `**~this is a method!~**`()
}

この書き方が用意されている本来の目的はJavaとの互換性を確保するところにあります。
JavaとKotlinでは予約語が異なり、一部の言葉が関数名として使用できません。
関数名を逆引用符で囲むことにより潜在的な競合を回避できます。

例えばJavaでは is は予約語で張りませんので is というメソッドがあったとします。

public static void is() {
    //…
}

Kotlinでは is は予約語ですので、このメソッドを呼び出すことはできません。
そこで逆引用符を用いて呼び出します。

fun doSomething(){
    `is`()
}

またテストコードの関数名に直感的な名前をつける目的で利用することもできます。

fun `This is a function`() {}
fun `users should be signed out when they click logout`() {}

こうした可読性を高めたテストコードの記述はTDDではベストプラクティスの一つです。
ちなみにテストコードの関数名は日本語で付けてもかまいません。
Kotlinのメソッドは日本語も受け付けますので、逆引用符などは必要ありません。

fun setNameメソッドの呼び出しテスト() {}
fun ログアウト押下時にサインアウトされるかのテスト() {}

KotlinLang: Function
Kotlin Programming — The Big Nerd Ranch Guide — Ch4函數