LoginSignup
9
9

More than 5 years have passed since last update.

Swift The Programming Language Functionsまとめ

Last updated at Posted at 2016-04-04

Functions

  • 関数は、特定のタスクを実行する独立したコードブロック
  • Swiftのすべての関数には型があり、関数のパラメータの型と戻り値の型で構成されます。
  • この型はSwiftの他の型と同様に使うことができるので、以下のことができる
    • 他の関数にパラメータとして関数を渡すこと
    • 関数から関数を返すこと
  • 関数のスコープ内で別の関数を記述することもできる

Defining and Calling Functions

Define Functions

  • 全ての関数は関数名を持ち、関数が実行するタスクを表現する
  • パラメータ: 任意。入力値として取る1つ以上の名前と型を持つパラメータを定義できる
  • 返り値: 任意。出力値として返す値の型を定義できる

Call Functions

  • 名前と関数のパラメータの型に一致する入力値(引数)を渡すことで関数が呼ばれる
  • 関数の引数は、関数のパラメータリストと同じ順序にする必要がある
func sayHelloAgain(personName: String) -> String {
    return "Hello again, " + personName + "!"
}

print(sayHelloAgain("Anna"))
// "Hello again, Anna!" と出力

Function Parameters and Return Values

Functions Without Parameters

  • パラメータを 1 つも取らない場合でも、関数名の後に丸括弧が必要
  • 関数を呼び出すときにも、関数名の後に丸括弧のペアが必要
func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())
// "hello, world" と出力

Functions With Multiple Parameters

  • 関数の丸括弧の中に、カンマ区切りで複数の入力パラメータを記述できる
  • 引数が異なれば、関数名が同じでも異なる関数とみなす
  • 呼ぶときは、一つ目のパラメータにはラベルは不要
func sayHello(personName: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return sayHelloAgain(personName)
    } else {
        return sayHello(personName)
    }
}
print(sayHello("Tim", alreadyGreeted: true))
// "Hello again, Tim!" と出力

Functions Without Return Values

  • 戻り値の型が定義されていない関数は、Voidtypeの特別な値を返します。
  • これは単に空のタプルで、() と記述できる
func sayGoodbye(personName: String) {
    print("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// "Goodbye, Dave!" と出力

Functions with Multiple Return Values

  • 複数の値で構成される戻り値を返すための型として、tuple typeを使用する
  • タプルが関数から返される時にtupleのメンバーに名前を付ける必要はない
func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

let bounds = minMax([8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
// "min is -6 and max is 109" と出力

Optional Tuple Return Types

  • 返り値のtuple全体の値がnilになり得ることを反映したい時にoptional tupleを使う
  • (Int, Int)?(String, Int, Bool)?とか
  • (Int,Int)?(Int?, Int?)は異なる
func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.isEmpty { return nil }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

Function Parameter Names

  • 関数のパラメータには、外部パラメータ名とローカルパラメータ名がある
  • 外部パラメータ名は、関数呼び出し時の引数に使う
  • ローカルパラメータ名は、関数の実装で使う

Specifying External Parameter Names

  • ローカルパラメータ名の前をスペースで区切って外部パラメータ名を記述する
  • 複数パラメータに外部パラメータ名を指定することで、呼び出すときにラベルを付ける必要がある
  • 関数の本体を読みやすく、意図を明確に維持したまま、表現力のある文章のように関数を呼び出せる
func sayHello(to person: String, and anotherPerson: String) -> String {
    return "Hello \(person) and \(anotherPerson)!"
}
print(sayHello(to: "Bill", and: "Ted"))
// "Hello Bill and Ted!" と出力

Omitting External Parameter Names

  • 関数の2つ目以降のパラメータに外部名を使用したくない場合には、明確な外部名ではなく_をパラメータに記述する
  • 1 つ目のパラメータは、デフォルトで外部パラメータ名を省略する
func someFunction(firstParameterName: Int, _ secondParameterName: Int) {
    // 1 つ目と 2 つ目のパラメータの引数値を
    // firstParameterName と secondParameterName で参照
}
someFunction(1, 2)

Default Parameter Values

  • パラメータの型の後に続けて値を代入することで、関数のどのパラメータにでもデフォルト値を定義できる
  • 関数を呼び出すときにそのパラメータを省略するとdefault valueで関数が実行される
  • 省略しないで引数を指定すると、その引数を元に関数を実行する

Variadic Parameters

  • 可変長(可変個)パラメータは、指定された型の値を 0 個以上受け取る
  • パラメータの型名の後にピリオドを 3 文字 (...) 挿入して可変長パラメータを記述する
func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// 5 つの数値の算術平均である 3.0 を返す
arithmeticMean(3, 8.25, 18.75)
// 3 つの数値の算術平均である 10.0 を返す

In-Out Parameters

  • 関数のパラメータの値を変更したい、かつ関数が終了した後もその変更を存続させたい場合に、そのパラメータを入出力パラメータとして定義する
  • パラメータのはじめにinoutキーワードを置く
  • 入出力パラメータは関数に渡される値で、関数によって変更され、もとの値を置き換えるために関数の外に戻される
  • 入出力パラメータは、関数本体のスコープの外に影響がある
  • 引数として変数のみ渡せる
  • 入出力パラメータに引数として渡すとき、関数によって変更されることを示すアンパサンド (&) を変数名の前に置く
func swapTwoInts(inout a: Int, inout _ b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// "someInt is now 107, and anotherInt is now 3" と出力

Function Types

  • すべての関数には、関数のパラメータの型と戻り値の型で構成される特定の関数型がある
  • func addTwoInts(a: Int, _ b: Int) -> Intの関数のtypeは(Int, Int) -> Intである
  • func printHelloWorld()の関数のtypeは() -> Voidである

Using Function Types

  • 関数型の定数または変数を定義し、適切な関数をその変数に代入することができる
var mathFunction: (Int, Int) -> Int = addTwoInts
let anotherMathFunction = addTwoInts
// anotherMathFunction は (Int, Int) -> Int 型と推論可能

Function Types as Parameter Types

  • 別の関数のパラメータの型として関数型を使用できる
func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// "Result: 8" と出力

Function Types as Return Types

  • 別の関数の戻り値の型として、関数型を使用できる
  • 関数が返す型として、->に続けて完全な関数型を記述します。
func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

Nested Functions

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero はネストされた関数 stepForward() を参照
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
9
9
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
9
9