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
- 戻り値の型が定義されていない関数は、
Void
typeの特別な値を返します。 - これは単に空のタプルで、() と記述できる
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!