Swift for iOS開発(6)-機能

バージョン

Xcode 11.0
Swift 5.1

関数の定義と呼び出し

関数は、特定のタスクを実行する独立したコードです。
関数を定義するとき、パラメータと呼ばれる関数の入力として名前と型を使用して1つ以上の値を定義するか、関数の実行の最後に呼び出される出力として特定の種類の値を定義することができます戻り値の型。
関数には、パラメーターや戻り値の型を含めることはできません。
一般的な執筆

func 函数名(形参1, 形参2) -> 返回类型 {
    
    
    // 函数体
}

例えば:

// 定义
func funcName(name: String, address: String) -> String {
    
    
    return name + "住在" + address
}

// 调用
print(funcName(name: "小明", address: "和磡村"))
// 打印 小明住在和磡村

パラメータと戻り値

1.パラメータなし

// 无参数
func sayHello() -> String {
    
    
    return "Hello, world"
}
print(sayHello())
// 打印 Hello, world

この関数にはパラメーターがありませんが、定義内の関数名の後に括弧のペアが必要です。呼び出されるときは、関数名の後に括弧のペアを記述する必要もあります。

2.複数のパラメータ

// 多参数
func teamMember(name1: String, name2: String, name3: String) -> String {
    
    
    return "团队成员有" + name1 + "," + name2 + "," + name3
}
print(teamMember(name1: "小明", name2: "小红", name3: "小黑"))
// 打印 团队成员有小明,小红,小黑

3.戻り値なし

// 无返回值
func printTeamMember(name1: String, name2: String, name3: String) {
    
    
    print("团队成员有\(name1), \(name2), \(name3)")
}
printTeamMember(name1: "小明", name2: "小红", name3: "小黑")
// 打印 团队成员有小明, 小红, 小黑

厳密に言えば、戻り値が明確に定義されていなくても、関数は値を返します。明確に定義された戻り値の型のない関数は、()として記述された空のタプルであるVoid型の特別な値を返します。

4.複数の戻り値(タプル型を返す)
次の例では、minMax(array :)という名前の関数が定義されています。これはInt型配列の最小値と最大値を見つけるために使用されます。

// 定义
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(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
// 打印“min is -6 and max is 109”

5.オプションのタプルの戻り値の型
関数によって返されるタプルの型がタプル全体に対して「値なし」である可能性がある場合、オプションのタプルの戻り値の型を使用して、タプル全体がnilになる可能性があるという事実を反映できます。(Int、Int)?や(String、Int、Bool)?などのタプルタイプの閉じ括弧の後に疑問符を配置することで、オプションのタプルを定義できます。


(Int、Int)?などのオプションのタプルタイプと(Int?、Int?)などのオプションのタイプを含むタプルは異なることに注意してくださいオプションのタプルタイプ。タプル内の各要素の値だけでなく、タプル全体がオプションです。

前のminMax(array :)関数は、2つのInt値を含むタプルを返します。ただし、この関数は渡された配列に対してセキュリティチェックを実行しません。配列パラメータが空の配列の場合、上記で定義されたminMax(array :)は、array [0]にアクセスしようとしたときにランタイムエラーをトリガーします。
この「空の配列」の問題を安全に処理するには、minMax(array :)関数を書き直して、オプションのタプル戻り値の型を使用し、配列が空の場合はnilを返します。

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)
}

if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
    
    
    print("min is \(bounds.min) and max is \(bounds.max)")
}
// 打印“min is -6 and max is 109”

パラメータラベルとパラメータ名

1.パラメータラベル
記事の冒頭に次のように例を書くことができます。

// 函数标签
func funcName1(student name: String, liveIn address: String) -> String {
    
    
    return "学生" + name + "住在" + address
}
print(funcName1(student: "小明", liveIn: "和磡村"))
// 打印 学生小明住在和磡村

パラメーター名の前にはラベルstudentが付き、パラメーターアドレスの前にはラベルliveInがあります。
ラベル付けの前に、関数はパラメーター名で呼び出されます。ラベル付け後、パラメーターラベルを使用する必要があります。

2.パラメータラベルを無視するパラメータにラベル
を追加したくない場合は、明示的なパラメータラベルの代わりにアンダースコア(_)を使用できます。

// 忽略函数标签
func funcName2(_ name: String, _ address: String) -> String {
    
    
    return "学生" + name + "住在" + address
}
print(funcName2("小明", "和磡村"))
// 打印 学生小明住在和磡村

3.デフォルトのパラメーター値
関数本体のパラメーターに値を割り当てることにより、任意のパラメーターのデフォルト値(デフォルト値)を定義できます。デフォルト値が定義されている場合、この関数を呼び出すときにこのパラメーターは無視できます。

// 默认参数值
func funcName3(name: String, address: String = "和磡村") -> String {
    
    
    return "学生" + name + "住在" + address
}
print(funcName3(name: "小明"))
// 打印 学生小明住在和磡村
print(funcName3(name: "小明", address: "白石洲"))
// 打印 学生小明住在白石洲

4.可変パラメーター
可変パラメーター(可変パラメーター)は、0個以上の値を受け入れることができます。関数を呼び出すときに、変数パラメーターを使用して、関数パラメーターに不確定な数の入力値を渡すことができるように指定できます。変数タイプ名の後に(...)を追加して、変数パラメーターを定義します。

// 可变参数
func funcName4(names: String..., address: String) -> String {
    
    
    var str = "学生"
    for name in names[0...] {
    
    
        str.append(name)
        str.append(" ")
    }
    str.append("住在")
    str.append(address)
    return str
}
print(funcName4(names: "小明", "小红", "小黑", address: "和磡村"))
// 打印 学生小明 小红 小黑 住在和磡村

注:
関数内に存在できる変数パラメーターは1つだけです。古いバージョンのSwiftは最後のパラメーターしか持つことができず、新しいバージョンはそれを制限しません。

5.入力および出力パラメーター
関数パラメーターはデフォルトで定数です。
入出力パラメーターを定義するときは、パラメーター定義の前にinoutキーワードを追加し、パラメーターを渡すときはパラメーター名の前にアンペアサンドを追加します。

// 输入输出参数
func assignment(number1: inout Int, number2: inout Int) {
    
    
    number1 = 20
    number2 = 30
}
var int1 = 0, int2 = 0
assignment(number1: &int1, number2: &int2)
print("int1 = \(int1), int2 = \(int2)")
// 打印 int1 = 20, int2 = 30

関数タイプ

各関数には特定の関数タイプがあり、関数タイプは関数のパラメータータイプと戻り値のタイプで構成されます。
例えば:

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

この関数の型は(Int、Int)-> Intであり、
「この関数型には2つのInt型パラメーターがあり、Int型値を返します」と解釈できます

もう一つの例:

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

この関数のタイプは次のとおりです。()-> Void、または「パラメーターがなく、Voidを返す関数」。

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

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

addTwoIntsとmathFunctionは同じ型であるため、この割り当てプロセスはSwiftの型チェックで許可されます。
これで、mathFunctionを使用して、割り当てられた関数を呼び出すことができます。

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

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

let anotherMathFunction = addTwoInts
// anotherMathFunction 被推断为 (Int, Int) -> Int 类型

2.パラメータタイプとしての関数タイプ関数タイプ
(Int、Int)-> Intを別の関数のパラメータタイプとして使用できます。このようにして、関数の実装の一部を関数の呼び出し元に任せて提供することができます。
これは別の例です。上記の関数と同様に、特定の数学演算の結果も出力します。

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

この例ではprintMathResult(定義3つのパラメータを取る:)機能:mathFunction、タイプ(INT、INT)と呼ばれる最初のパラメータは- > INTは、あなたが関数のこのタイプのいずれかを渡すことができ、2番目と3番目のパラメータが呼び出されaとb、およびそれらの型は両方ともIntです。これらの2つの値は、指定された関数の入力値として使用されます。
printMathResultが(場合
:)起動され、それがaddTwoInts関数と3と5の整数を渡されます。3と5でaddTwoIntsを呼び出し、結果を出力します:8。

3.戻り
値の型としての関数型関数型を別の関数の戻り値の型として使用できます。あなたがする必要があるのは、戻り矢印(->)の後に完全な関数型を書くことです。
次の例では、stepForward(:)とstepBackward(:)という2つの単純な関数が定義されています。stepForward(:)関数は、入力値より1大きい値を返します。stepBackward(:)関数は、入力値より1つ小さい値を返します。これら2つの関数のタイプは両方とも(Int)-> Intです。

func stepForward(_ input: Int) -> Int {
    
    
    return input + 1
}
func stepBackward(_ input: Int) -> Int {
    
    
    return input - 1
}

次の関数chooseStepFunction(backward :)は、戻り値の型が(Int)-> Int型関数です。choiceStepFunction(backward :)は、ブール値の後方に応じて、stepForward(:)関数またはstepBackward( :)関数を返します

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

これで、chooseStepFunction(backward :)を使用して、次の2つの関数のいずれかを取得できます。

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero 现在指向 stepBackward() 函数。

上記の例では、currentValueが徐々に0に近づいて正の数になるか、負の数になるかが計算されます。currentValueの初期値は3です。これは、currentValue> 0がtrueであることを意味します。これにより、chooseStepFunction(:)はstepBackward(:)関数を返します。返された関数への参照は、moveNearerToZero定数に格納されます。
ここで、moveNearerToZeroは正しい関数を指しており、これを使用してゼロまでカウントできます。

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

入れ子関数

この章でこれまで見てきたすべての関数はグローバル関数と呼ばれ、グローバルドメインで定義されています。入れ子関数と呼ばれる他の関数本体で関数を定義することもできます。
デフォルトでは、ネストされた関数は外部からは見えませんが、それを囲む関数から呼び出すことができます。周辺関数は、ネストされた関数の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!

おすすめ

転載: blog.csdn.net/u012078168/article/details/103700671