3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kotlinまとめ - 文法詳解 - 関数

Last updated at Posted at 2018-07-14

関数

// 普通の書き方
fun square(x: Int): Int {
    return x * x
}

// 簡略した
fun square(x: Int): Int = x * x
// 型推論もできるので、推論できる場合は戻り値の型も省略可能
fun square(x: Int) = x * x

たとえ簡単で1行で表現できたとしても{}で囲ったほうが統一感が出ていいかもと思っている
現時点での気持ちなので、「短いは正義!!」とか気持ちが変わるかもしれない。

名前付き引数

fun square(x: Int): Int {
    return x * x
}
val squared = square(x = 1)
// 最新のIntelliJ IDEA とか Android Studioは引数のラベルを表示してくれるけど
// こう書いたほうがGit上での差分を見るときには読みやすそう
// Swiftはこのラベルが自動的に表示されてくれるからそのほうがうれしい

// ラベルの順番はどうでもいい
fun add(x: Int, y: Int) = x + y
val added = add(y = 1, x = 2)

デフォルト引数

fun printHello(name: String = "guest") = println("hello, $name")

printHello()                 // hello, guest
printHello(name = "hicka04") // hello, hicka04

可変長変数

  • varargを引数の前につけるだけで、引数を配列として受け取ることができるようになる
  • 可変長変数は1つの関数につき1つまで
fun sum(vararg ints: Int): Int {
    var sum = 0
    for (i in ints) {
        sum += i
    }
    return sum
}

println(sum(1, 2, 3)) // 6
// 配列を渡すときは`*`を先頭につける必要がある
println(sum(ints = *intArrayOf(1, 2, 3)))

再帰呼び出し

使わないパターン

fun sum(numbers: List<Long>): Long {
    var sum = 0L
    for (n in numbers) {
        sum += n
    }
    return sum
}

使うパターン

リストが空になるまで「最初の要素」と「最初の要素以外のリストの合計」を出す

fun sum(numbers: List<Long>): Long =
    if (numbers.isEmpty()) 0
    else numbers.first() + sum(numbers.drop(1))

注意点

  • 再帰呼び出しの回数が多いとスタックを食いつぶし、スタックオーバーフローでクラッシュする可能性がある
  • スタックを消費しないように再帰呼び出しを最適化してくれる仕組みがある
    TCO(Tail Call Optimization, 末尾呼び出し最適化)
  • 再帰呼び出しを関数の最後の計算になるように変更する必要がある
tailrec fun sum(numbers: List<Long>, accumulator: Long = 0): Long =
    if (numbers.isEmpty()) accumulator
    else sum(numbers.drop(1), accumulator + numbers.first())

ローカル関数

  • 関数内に別の関数を定義すること
    • スコープを限定的にしたいときなど
  • 上記のsum(numbers:accumulator:)はいかなる場合においてもaccumulatorが0になっていてほしいが、デフォルト引数で渡しているだけなので、初期値0の縛りをかけたい
// go(numbers:accumulator:)はさっきのsum(numbers:accumulator:)と同じ
// このsumを呼び出す側にはaccumulatorが見えなくなった
fun sum(numbers: List<Long>): Long {
    tailrec fun go(numbers: List<Long>, accumulator: Long = 0): Long = 
            if (numbers.isEmpty()) accumulator
            else go(numbers.drop(1), accumulator + numbers.first())
    
    return go(numbers, 0)
}

値を返さない関数

  • 返り値の型にUnitを指定する
  • Kotlin:Unit == Java:void
  • Unit省略するのが普通(だよね、知ってた)
fun printHoge(): Unit {
    println("hoge")
}

fun printHoge() = println("hoge")

←基本的な文法 - 条件分岐, ループ || 文法詳解 - 第一級オブジェクトとしての関数→

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?