Edited at

Swift The Programming Language Functionsまとめ

More than 3 years have passed since last update.


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!