100 Days of SwiftUI —— Day 7:闭包 (下)

100 Days of SwiftUI —— Day 7:闭包 (下)_第1张图片

昨天您了解了闭包的基础知识,但是今天情况变得有些棘手了。但这没关系:本杰明·富兰克林(美国总统)曾经说过:“活力与毅力可以征服一切(energy and persistence conquer all things)” ——你可以做到!

有时候闭包语法会让你觉得有点难,这在你学习今天的课程时会很明显。如果您觉得它有点让人不知所措,或者您盯着某些代码不能100%确定是什么意思——只需返回一个视频并再次观看,以便能加深您的记忆。

提醒一下,SwiftUI广泛使用闭包,因此值得花时间真正了解此处的情况。是的,它们可能是Swift最复杂的功能,但这有点像在山上骑自行车——一旦到达顶峰,一旦掌握了闭包,一切将变得更加容易。

Closure

今天,您有7个一分钟的视频可供观看,并且您将了解闭包如何接受参数并返回值。完成每个视频后,将进行简短测试,以确保您了解了所教的内容。

1. 当闭包接受参数时,将其用作参数 Using closures as parameters when they accept parameters – test

在这里可以开始读取闭包,有点像线噪声:传递给函数的闭包也可以接受其自己的参数。

我们一直在使用()->Void表示“不接受任何参数,不返回任何内容”,但是您可以继续填充()闭包应接受的任何参数的类型。

为了说明这一点,我们可以编写一个travel()函数,该函数接受一个闭包作为其唯一参数,然后该闭包又接受一个字符串:

func travel(action: (String) -> Void) {
    print("I'm getting ready to go.")
    action("London")
    print("I arrived!")
}

现在,当我们使用结尾封闭语法调用travel()时,我们的闭包代码需要接收字符串:

travel { (place: String) in
    print("I'm going to \(place) in my car")
}

2. 闭包返回值时,将其用作参数 Using closures as parameters when they return values – test

我们一直在使用()-> Void来表示“不接受任何参数,不返回任何内容”,但是您可以将该Void替换为任何类型的数据,以强制闭包返回值。

为了说明这一点,我们可以编写一个travel()函数,该函数接受一个闭包作为唯一参数,然后该闭包又接受一个字符串并返回一个字符串:

func travel(action: (String) -> String) {
    print("I'm getting ready to go.")
    let description = action("London")
    print(description)
    print("I arrived!")
}

现在,当我们使用结尾闭包语法调用travel()时,需要闭包代码接受一个字符串并返回一个字符串:

travel { (place: String) -> String in
    return "I'm going to \(place) in my car"
}

3. 参数名称缩写 Shorthand parameter names – test

我们刚刚写了一个travel()函数。它接受一个参数,这是一个闭包,其本身接受一个参数并返回一个字符串。然后在两次调用print()之间运行该闭包。这是代码:

func travel(action: (String) -> String) {
    print("I'm getting ready to go.")
    let description = action("London")
    print(description)
    print("I arrived!")
}

我们可以使用以下方式调用travel()

travel { (place: String) -> String in
    return "I'm going to \(place) in my car"
}

但是,Swift知道该闭包的参数必须是字符串,因此我们可以将其删除:

travel { place -> String in
    return "I'm going to \(place) in my car"
}

它也知道闭包必须返回一个字符串,因此我们可以删除它:

travel { place in
    return "I'm going to \(place) in my car"
}

由于闭包只有一行代码必须是返回值的那一行,因此Swift也允许我们删除return关键字:

travel { place in
    "I'm going to \(place) in my car"
}

Swift具有简化的语法,可让您写得更简短。我们可以让Swift为闭包的参数提供自动名称,而不必写place in。这些名称以$命名,然后从0开始计数:

travel {
    "I'm going to \($0) in my car"
}

4. 具有多个参数的闭包 Closures with multiple parameters – test

为了弄清一切,我们将编写另一个使用两个参数的闭包的示例。

这次,我们的travel()函数将需要一个闭合,该闭包需要指定某人要去的地方以及他们的速度。这意味着我们需要使用(String,Int)-> String作为参数的类型:

func travel(action: (String, Int) -> String) {
    print("I'm getting ready to go.")
    let description = action("London", 60)
    print(description)
    print("I arrived!")
}

我们将使用尾随闭包和简写闭包参数名称来调用它。由于此方法接受两个参数,因此我们将同时获得$ 0$ 1

travel {
    "I'm going to \($0) at \($1) miles per hour."
}

有些人不喜欢使用速记参数名称,例如$ 0,因为它可能会造成混淆,这没关系——做适合您自己的事情,不喜欢则不用。

5. 从函数返回闭包 Returning closures from functions – test

和将闭包传递给函数的方式相同,也可以从函数返回闭包。

首先,这样做的语法有点混乱,因为它使用->两次:一次是指定函数的返回值,第二次是指定闭包的返回值。

为了搞清楚这个问题,我们将编写一个travel()函数,该函数不接受任何参数,但返回一个闭包。返回的闭包必须使用字符串调用,并且不会返回任何内容:

func travel() -> (String) -> Void {
    return {
        print("I'm going to \($0)")
    }
}

现在,我们可以调用travel()来获取该闭包,然后将其作为一个函数调用:

let result = travel()
result("London")

接从travel()调用返回值,尽管实际上不建议这样做,但是技术上讲是允许的:

let result2 = travel()("London")

6. 捕获值 Capturing values – test

如果您在闭包内部使用任何外部值,则Swift会捕获它们——将它们和闭包存储在一起,因此即使它们不再存在也可以对其进行修改。

现在,我们有一个travel()函数,它返回一个闭包,并且返回的闭包接受字符串作为其唯一参数,并且不返回任何内容:

func travel() -> (String) -> Void {
    return {
        print("I'm going to \($0)")
    }
}

我们可以调用travel()返回该闭包,然后自由调用该闭包:

let result = travel()
result("London")

如果我们在在闭包内部使用了travel()中创建的值,则会发生闭包捕获。例如,我们可能想跟踪返回的闭包被调用的频率:

func travel() -> (String) -> Void {
    var counter = 1

    return {
        print("\(counter). I'm going to \($0)")
        counter += 1
    }
}

即使该计数器变量是在travel()内部创建的,它也被闭包捕获,因此对于该闭包仍将保持活动状态。

因此,如果我们多次调用result(“ London”),则计数器将不断增加:

result("London")
result("London")
result("London")

7. 闭包:总结 Closures summary – test

您已经完成了本系列第六部分,所以让我们总结一下:

1、您可以将闭包分配给变量,然后再调用它们。
2、闭包可以接受参数和返回值,例如常规函数。
3、您可以将闭包作为参数传递给函数,并且这些闭包可以具有自己的参数和返回值。
4、如果函数的最后一个参数是闭包,则可以使用尾随闭包语法。
5、Swift会自动提供诸如$ 0$ 1之类的参数缩写名称,但并非每个人都使用它们。
6、如果在闭包内部使用外部值,则将捕获它们,以便闭包以后可以引用它们。

赏我一个赞吧~~~

你可能感兴趣的:(100 Days of SwiftUI —— Day 7:闭包 (下))