【Swift学習】Swiftプログラミングの旅---関数(十)
19739 ワード
関数は、特定のタスクを実行するための独立したコード・セグメントのセットで、関数を「呼び出し」関数で実行するための名前で識別します.
swift統合関数の構文は、パラメータを持たない単純な名前とローカルおよび外部の各パラメータのパラメータ名の複雑なobjective-c-style Cスタイルの関数方法を表現するのに十分な柔軟性を有する.パラメータは、関数呼び出しを簡略化するためにデフォルト値を提供し、出力パラメータで機能が完了すると、伝達された変数を変更できます.
swiftの各関数には、パラメータタイプと戻りタイプからなるタイプがあります.このタイプの他のタイプを使用すると、パラメータの他の関数として関数を簡単に返し、関数の関数を返すことができます.関数は、ネストされた関数の役割ドメイン内の有用な関数を他の関数でカプセル化することもできます.
関数の定義と呼び出し
sayHelloは関数の名前で、personNameはそのパラメータで、タイプはStringで、Stringタイプのデータを返して、->記号を使って関数の戻りタイプを識別して、後ろは関数の戻りタイプです.
関数のパラメータと戻り値
関数パラメータと戻り値は非常に柔軟です.単純なユーティリティ関数から任意の単純な関数を定義し、名前の付いていないパラメータで複雑な関数を定義できます.
パラメトリック関数なし
たじゅうパラメータかんすう
戻り値関数なし(実際にvoidを返す)
マルチリターン関数
関数パラメータ名
関数のパラメータには、ローカルパラメータと外部パラメータ名が含まれます.外部パラメータ名は、パラメータを関数呼び出しに渡すために使用されます.関数の実装にローカルパラメータ名が使用されています
既定のパラメータ値
パラメータタイプの後に任意のパラメータにデフォルト値を設定できます.デフォルト値を設定すると、関数を呼び出すときにこのパラメータを無視できます.
関数のパラメータリストの末尾にデフォルト値を設定
可変パラメータ
1つの可変パラメータは、特定のタイプの0つ以上の値を受け入れます.関数が呼び出されると、可変パラメータを使用して、異なる数の指定したタイプのパラメータを入力し、パラメータタイプ名の後ろに...を挿入して可変パラメータを実現します.関数体の可変パラメータ値は、特定のタイプの配列として処理される.例は以下の通り
numbers:Double...Doubleタイプを格納する配列として扱われ、各要素を巡回することができます.
注意:1つの関数には1つの可変パラメータしかありません
In-Outパラメータ
関数パラメータのデフォルトは定数で、関数内でパラメータ値を変更するとコンパイル時にエラーが発生します.これは、パラメータの値を変更できないことを意味します.パラメータの値を変更し、関数呼び出しが終了した後に永続的に変更したい場合は、 In-outパラメータの代わりに
inoutキーワードを使用してin-outパラメータを定義しますが、パラメータは定数ではなく、変数のみです.呼び出すと、パラメータ名に&記号を付けて、このパラメータが関数によって変更できることを識別します.
呼び出し方法を見てみましょう
関数のタイプ
各関数には、パラメータタイプと関数の戻りタイプからなる特定の関数タイプがあります.
この例ではaddTwoInts,multiplyTwoIntsの2つの関数を定義し,それらのタイプはすべて(Int,Int)->Int
そのタイプは()->Void
関数タイプの使用
swiftでは、他のタイプと同様に関数タイプを使用できます.たとえば、定数または変数を関数タイプとして定義し、変数に対応する関数を指定できます.
「mathFunction変数という名前を定義します.この変数のタイプは'1つの関数で、2つのInt値を受け入れ、1つのInt値を返します.'この新しい変数を設定してaddTwoInts関数という名前を参照します.
このaddTwoInts関数はmathFunctionと同じタイプの変数を持つので,この付与はswiftのタイプチェックに合格できる.
mathFunctionを使用して、指定した関数を呼び出すことができます.
他のタイプと同様に、関数に定数または変数を割り当てると、Swiftに関数のタイプを推定させることができます.
パラメータタイプとしての関数タイプ
(Int,Int)->Intなどの関数タイプを別の関数のパラメータタイプとして使用できます.これにより、呼び出し元が提供する関数が呼び出されるように、関数のいくつかの態様の関数実装が予約されます.
戻りタイプとしての関数タイプ
1つの関数タイプを別の関数の戻りタイプとして使用できます.戻り関数の戻り矢印(->)その後、完全な関数タイプを作成して実装します.次の例では、stepForwardとstepBackwardを呼び出す2つの簡単な関数を定義します.stepForward関数は入力値+1の結果を返し、stepBackward関数は入力値-1の結果を返します.両方の関数には同じ(Int)->Intタイプがあります.
ネスト関数
これまでこの章で出会ったすべての関数はグローバル関数であり、グローバル役割ドメインで定義されています.実際には、ネスト関数と呼ばれる他の関数体で関数を定義することもできます.ネスト関数のデフォルトは外部には非表示ですが、パッケージされた関数で呼び出され、使用できます.enclosing functionはネスト関数を返して、ネスト関数を返すこともできます.他の役割ドメインではネスト関数を使用します.上のchooseStepFunctionの例を書き換えてネスト関数を使用して返します.
swift統合関数の構文は、パラメータを持たない単純な名前とローカルおよび外部の各パラメータのパラメータ名の複雑なobjective-c-style Cスタイルの関数方法を表現するのに十分な柔軟性を有する.パラメータは、関数呼び出しを簡略化するためにデフォルト値を提供し、出力パラメータで機能が完了すると、伝達された変数を変更できます.
swiftの各関数には、パラメータタイプと戻りタイプからなるタイプがあります.このタイプの他のタイプを使用すると、パラメータの他の関数として関数を簡単に返し、関数の関数を返すことができます.関数は、ネストされた関数の役割ドメイン内の有用な関数を他の関数でカプセル化することもできます.
関数の定義と呼び出し
func sayHello(personName: String) -> String { let greeting = "Hello, " + personName + "!" return greeting }
print(sayHello("Anna")) // Prints "Hello, Anna!" print(sayHello("Brian")) // Prints "Hello, Brian!
sayHelloは関数の名前で、personNameはそのパラメータで、タイプはStringで、Stringタイプのデータを返して、->記号を使って関数の戻りタイプを識別して、後ろは関数の戻りタイプです.
関数のパラメータと戻り値
関数パラメータと戻り値は非常に柔軟です.単純なユーティリティ関数から任意の単純な関数を定義し、名前の付いていないパラメータで複雑な関数を定義できます.
パラメトリック関数なし
func sayHelloWorld() -> String { return "hello, world" } print(sayHelloWorld()) // Prints "hello, world
たじゅうパラメータかんすう
func sayHello(personName: String, alreadyGreeted: Bool) -> String { if alreadyGreeted { return sayHelloAgain(personName) } else { return sayHello(personName) } } print(sayHello("Tim", alreadyGreeted: true)) // Prints "Hello again, Tim!
戻り値関数なし(実際にvoidを返す)
func sayGoodbye(personName: String) { print("Goodbye, \(personName)!") } sayGoodbye("Dave") // Prints "Goodbye, Dave!
func printAndCount(stringToPrint: String) -> Int { print(stringToPrint) return stringToPrint.characters.count } func printWithoutCounting(stringToPrint: String) { printAndCount(stringToPrint) } printAndCount("hello, world") // prints "hello, world" and returns a value of 12 printWithoutCounting("hello, world") // prints "hello, world" but does not return a value
マルチリターン関数
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)") // Prints "min is -6 and max is 109
関数パラメータ名
関数のパラメータには、ローカルパラメータと外部パラメータ名が含まれます.外部パラメータ名は、パラメータを関数呼び出しに渡すために使用されます.関数の実装にローカルパラメータ名が使用されています
func someFunction(firstParameterName: Int, secondParameterName: Int) { // function body goes here // firstParameterName and secondParameterName refer to // the argument values for the first and second parameters } someFunction(1, secondParameterName: 2)
既定のパラメータ値
パラメータタイプの後に任意のパラメータにデフォルト値を設定できます.デフォルト値を設定すると、関数を呼び出すときにこのパラメータを無視できます.
func someFunction(parameterWithDefault: Int = 12) { // function body goes here // if no arguments are passed to the function call, // value of parameterWithDefault is 12 } someFunction(6) // parameterWithDefault is 6 someFunction() // parameterWithDefault is 12
関数のパラメータリストの末尾にデフォルト値を設定
可変パラメータ
1つの可変パラメータは、特定のタイプの0つ以上の値を受け入れます.関数が呼び出されると、可変パラメータを使用して、異なる数の指定したタイプのパラメータを入力し、パラメータタイプ名の後ろに...を挿入して可変パラメータを実現します.関数体の可変パラメータ値は、特定のタイプの配列として処理される.例は以下の通り
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) // returns 3.0, which is the arithmetic mean of these five numbers arithmeticMean(3, 8.25, 18.75) // returns 10.0, which is the arithmetic mean of these three numbers
numbers:Double...Doubleタイプを格納する配列として扱われ、各要素を巡回することができます.
注意:1つの関数には1つの可変パラメータしかありません
In-Outパラメータ
関数パラメータのデフォルトは定数で、関数内でパラメータ値を変更するとコンパイル時にエラーが発生します.これは、パラメータの値を変更できないことを意味します.パラメータの値を変更し、関数呼び出しが終了した後に永続的に変更したい場合は、 In-outパラメータの代わりに
inoutキーワードを使用してin-outパラメータを定義しますが、パラメータは定数ではなく、変数のみです.呼び出すと、パラメータ名に&記号を付けて、このパラメータが関数によって変更できることを識別します.
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)") // Prints "someInt is now 107, and anotherInt is now 3”
関数のタイプ
各関数には、パラメータタイプと関数の戻りタイプからなる特定の関数タイプがあります.
func addTwoInts(a: Int, _ b: Int) -> Int { return a + b } func multiplyTwoInts(a: Int, _ b: Int) -> Int { return a * b }
この例ではaddTwoInts,multiplyTwoIntsの2つの関数を定義し,それらのタイプはすべて(Int,Int)->Int
func printHelloWorld() { print("hello, world") }
そのタイプは()->Void
関数タイプの使用
swiftでは、他のタイプと同様に関数タイプを使用できます.たとえば、定数または変数を関数タイプとして定義し、変数に対応する関数を指定できます.
var mathFunction: (Int, Int) -> Int = addTwoInts
「mathFunction変数という名前を定義します.この変数のタイプは'1つの関数で、2つのInt値を受け入れ、1つのInt値を返します.'この新しい変数を設定してaddTwoInts関数という名前を参照します.
このaddTwoInts関数はmathFunctionと同じタイプの変数を持つので,この付与はswiftのタイプチェックに合格できる.
mathFunctionを使用して、指定した関数を呼び出すことができます.
print("Result: \(mathFunction(2, 3))") // Prints "Result: 5
他のタイプと同様に、関数に定数または変数を割り当てると、Swiftに関数のタイプを推定させることができます.
let anotherMathFunction = addTwoInts // anotherMathFunction is inferred to be of type (Int, Int) -> Int
パラメータタイプとしての関数タイプ
(Int,Int)->Intなどの関数タイプを別の関数のパラメータタイプとして使用できます.これにより、呼び出し元が提供する関数が呼び出されるように、関数のいくつかの態様の関数実装が予約されます.
func printMathResult(mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) { print("Result: \(mathFunction(a, b))") } printMathResult(addTwoInts, 3, 5) // Prints "Result: 8
戻りタイプとしての関数タイプ
1つの関数タイプを別の関数の戻りタイプとして使用できます.戻り関数の戻り矢印(->)その後、完全な関数タイプを作成して実装します.次の例では、stepForwardとstepBackwardを呼び出す2つの簡単な関数を定義します.stepForward関数は入力値+1の結果を返し、stepBackward関数は入力値-1の結果を返します.両方の関数には同じ(Int)->Intタイプがあります.
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 }
var currentValue = 3 let moveNearerToZero = chooseStepFunction(currentValue > 0) // moveNearerToZero now refers to the stepBackward() function
print("Counting to zero:") // Counting to zero: while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // 3... // 2... // 1... // zero!
ネスト関数
これまでこの章で出会ったすべての関数はグローバル関数であり、グローバル役割ドメインで定義されています.実際には、ネスト関数と呼ばれる他の関数体で関数を定義することもできます.ネスト関数のデフォルトは外部には非表示ですが、パッケージされた関数で呼び出され、使用できます.enclosing functionはネスト関数を返して、ネスト関数を返すこともできます.他の役割ドメインではネスト関数を使用します.上のchooseStepFunctionの例を書き換えてネスト関数を使用して返します.
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 now refers to the nested stepForward() function while currentValue != 0 { print("\(currentValue)... ") currentValue = moveNearerToZero(currentValue) } print("zero!") // -4... // -3... // -2... // -1... // zero!