見出し画像

Swiftでプログラミング。 -関数 3

Function Types 

関数には特定の関数型をとるものがあり、パラメーター型と関数の戻り値で構成されています。例えば:

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

この例では、addTwoIntsおよびmultiplyTwoIntsと呼ばれる2つの単純な数学関数を定義します。 これらの関数はそれぞれ2つのInt値を取り、適切な数学演算を実行した結果であるInt値を返します。

これらの関数の両方のタイプは、(Int、Int)-> Intです。 これは次のように読むことができます:

「Int型の2つのパラメーターを持ち、Int型の値を返す関数。」

パラメータや戻り値のない関数について次に示します。

    func printHelloWorld() {
       print("hello, world")
   }

この関数のタイプは、()-> Void、または「パラメーターを持たず、Voidを返す関数」です。

Using Function Types 

Swiftの他のタイプと同じように関数タイプを使用します。 たとえば、定数または変数を関数型として定義し、その変数に適切な関数を割り当てることができます。

var mathFunction: (Int, Int) -> Int = addTwoInts

これは次のように読むことができます:

「「2つのInt値を取り、Int値を返す関数」の型を持つmathFunctionという変数を定義します。この新しい変数を、addTwoIntsという関数を参照するように設定します。」

addTwoInts(_:_ :)関数はmathFunction変数と同じ型であるため、この割り当てはSwiftの型チェッカーによって許可されます。

これで、割り当てられた関数をmathFunctionという名前で呼び出すことができます。

   print("Result: \(mathFunction(2, 3))")
   // Prints "Result: 5"

非関数タイプの場合と同じ方法で、同じ一致タイプの異なる関数を同じ変数に割り当てることができます。

   mathFunction = multiplyTwoInts
   print("Result: \(mathFunction(2, 3))")
   // Prints "Result: 6"

他のタイプと同様に、定数または変数に関数を割り当てるときに、関数タイプを推測するためにSwiftに任せることができます。

    let anotherMathFunction = addTwoInts
   // anotherMathFunction is inferred to be of type (Int, Int) -> Int

Function Types as Parameter Types  パラメータタイプとしての関数タイプ

(Int、Int)-> Intなどの関数型を別の関数のパラメーター型として使用できます。 これにより、関数の実装のいくつかの側面を、関数が呼び出されたときに関数の呼び出し元が提供できるようにすることができます。

上からmathFunctionの結果を出力する例を次に示します。

   func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
       print("Result: \(mathFunction(a, b))")
   }
   printMathResult(addTwoInts, 3, 5)
   // Prints "Result: 8"

この例では、3つのパラメーターを持つprintMathResult(_:_:_ :)という関数を定義します。 最初のパラメーターはmathFunctionが呼ばれます。タイプ(Int、Int)-> Intです。 この最初のパラメーターの引数として、そのタイプの任意の関数を渡すことができます。 2番目と3番目のパラメーターはaとbと呼ばれ、どちらもInt型です。 これらは、提供された数学関数の2つの入力値として使用されます。

printMathResult(_:_:_ :)が呼び出されると、addTwoInts(_:_ :)関数、および整数値3と5が渡されます。提供された関数を値3と5で呼び出し、次の結果を出力します。 8.8。

printMathResult(_:_:_ :)の役割は、適切なタイプの数学関数の呼び出しの結果を出力することです。 その関数の実装が実際に何をするかは重要ではありません。関数が正しいタイプであることが重要です。 これにより、printMathResult(_:_:_ :)は、その機能の一部を関数の呼び出し元にタイプセーフな方法で渡すことができます。

Function Types as Return Types   戻り型としての関数型

関数型を別の関数の戻り型として使用できます。 これを行うには、戻り関数の戻り矢印(->)の直後に完全な関数型を記述します。

次の例では、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
   }

これがchooseStepFunction(backward :)という関数で、その戻り型は(Int)-> Intです。 ChooseStepFunction(backward :)関数は、backward:と呼ばれるブールパラメーターに基づいてstepForward(_ :)関数またはstepBackward(_ :)関数を返します。

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

これで、chooseStepFunction(backward :)を使用して、一方向または他の方向にステップする関数を取得できます。

   var currentValue = 3
   let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
   // moveNearerToZero now refers to the stepBackward() function

上記の例では、currentValueという変数を徐々にゼロに近づけるために正または負のステップが必要かどうかを判断します。 currentValueの初期値は3です。これは、currentValue> 0がtrueを返し、chooseStepFunction(backward :)がstepBackward(_ :)関数を返すことを意味します。 返された関数への参照は、moveNearerToZeroという定数に格納されます。

moveNearerToZeroが正しい関数を参照するようになったので、これを使用してゼロまでカウントできます。

   print("Counting to zero:")
   // Counting to zero:
   while currentValue != 0 {
       print("\(currentValue)... ")
       currentValue = moveNearerToZero(currentValue)
   }
   print("zero!")
   // 3...
   // 2...
   // 1...
   // zero!

Nested Functions  入れ子関数

この章でこれまでに遭遇したすべての関数は、グローバルスコープで定義されたグローバル関数の例です。 入れ子関数と呼ばれる、他の関数の本体内に関数を定義することもできます。

ネストされた関数は、デフォルトでは外部から隠されていますが、それを囲む関数によって呼び出して使用することができます。 囲んでいる関数は、ネストされた関数の1つを返して、ネストされた関数を別のスコープで使用できるようにすることもできます。

上記のchooseStepFunction(backward :)の例を書き直して、ネストされた関数を使用して返すことができます。

   func chooseStepFunction(backward: Bool) -> (Int) -> Int {
       func stepForward(input: Int) -> Int { return input + 1 }
       func stepBackward(input: Int) -> Int { return input - 1 }
       return backward ? stepBackward : stepForward
   }
   var currentValue = -4
   let moveNearerToZero = chooseStepFunction(backward: 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!


この記事が気に入ったらサポートをしてみませんか?