タコさんブログ

プログラミングメモと小言

The Swift Programming LanguageのFunctionsメモ

前回の続き。Constants and Variable Parametersあたりから。

関数のパラメータ

関数のパラメータはデフォルトで定数パラメータになる。つまり、パラメータの前に何も書かなければではletが自動でつく。明示的に関数を書くと下のようになる。

func someFunction(let number: Int) {
    number++  // 定数なのでエラーになる
    println(number)
}

定数から変数パラメータに変更するには明示的にvarをつける。上の例でエラーにならないようにするには、以下のように書く。

func someFunction(var number: Int) {
    number++ // 変数なのでOK
    println(number)
}

※関数内でパラメータの変数に変更を加えても関数の外では変更されないので注意

In-Outパラメータ

通常、関数の中でパラメータの変数に変更を加えても、関数の外では変更されないが、inoutキーワードをパラメータの前につけることで、変更することが可能になる。C言語で言うところのアドレス渡し。C言語でよく見るswap関数をswiftで書くと次のようになる。

func swap(inout a: Int, inout b: Int) {
    let tmp = a
    a = b
    b = tmp
}

var a = 1
var b = 2
swap(&a, &b)  // &をつけて渡す
println("a = \(a), b = \(b)")  // a = 2, b = 1

inoutで出来ないこと。

  • デフォルト値の設定
  • 可変長パラメータには使用できない
  • inoutを使用すると、var、letを使用できない

関数型 (Function Type)

関数型はパラメータの型と戻り値の型で決まる。
例えば下の関数型は, Int -> Int型になる。

func someFunc(number: Int) -> Int {
    println(number)
}

下の例は、引数も戻り値もない関数。
この場合、() -> ()型になる。

func sayHello() {
    println("Hello")
}

関数型を利用して、関数型の変数を扱うことができる。

func addOne(number: Int) -> Int {
    return number + 1
}

let anotherAddOne: Int -> Int = addOne // 型推論により Int -> Int 省略できる

anotherAddOne(1) // 出力:2

パラメータ・戻り値としての関数型

関数型を利用して、関数のパラメータの型に使用できる。

func printFunc(functionToPrint: (Int, Int) -> Int) {
    println("\(functionToPrint(1, 2))")
}

func addTwoInts(a: Int, b: Int) -> Int {
    return a + b
}

printFunc(addTwoInts)  // 出力:3

また、戻り値の型に関数型を指定すれば、関数を戻り値として返す関数が宣言できる。

func returnAddOne()->Int -> Int {
    return addOne
}

returnAddOne()(1)  // 出力:2

関数のネスト

関数の中に関数を宣言して、関数をネストすることができる。

func outerFunction() {
    
    func innerFunction() {
        println("Inner Function")
    }
    
    innerFunction()
    
    println("Outer Function")
}

outerFunction()  // "Inner Function" が出力されてから "Outer Function" が出力される

次回はCloserのセクションから