gpt4 book ai didi

swift - 带括号的 Swift 中闭包的输入参数

转载 作者:搜寻专家 更新时间:2023-10-30 22:23:54 24 4
gpt4 key购买 nike

我正在学习以下关于 RxSwift 的教程:

http://adamborek.com/thinking-rxswift/

并且无法理解以下模式:

           searchBar.rx.text.orEmpty
------------> .flatMap { [spotifyClient] query in
return spotifyClient.rx.search(query: query)
}.map { tracks in
return tracks.map(TrackRenderable.init)
}

这个方括号输入参数:[spotifyClient] query 对我来说似乎很奇怪。我查看了有关闭包和函数的官方 Apple 文档,但看不到此类输入参数的任何示例。在 Objective C 中,这不会让我很困扰,但它是 Swift。谁能解释一下,这个参数在这里意味着什么?

最佳答案

您需要了解闭包的变量捕获理念。

考虑这个例子:

struct Calculator {
var a: Int
var b: Int

var sum: Int {
return a + b
}
}

然后您将其用作:

let calculator = Calculator(a: 3, b: 5)

// You define a closure where you will use this calculator instance
let closure = {
// closure captures the variables that are declared prior to the declaration of the closure.
// your calculator instance is being captured here
// it's default variable capture
print("The result is \(calculator.sum)")
}

closure() // Prints "The result is 8"

到目前为止,一切正常。您得到了预期的结果。

现在假设您将计算器实例声明为 var,因为在某些时候您需要改变它的状态。这就是出现复杂性的情况。看:

var calculator = Calculator(a: 3, b: 5)

let closure = {
print("The result is \(calculator.sum)")
}

// You change the state of your calculator instance anytime before the closure gets executed
calculator.b = 20
// When the closure actually executes, you will be affected by any changes outside the closure
closure() // Prints "The result is 23"

因此,默认变量捕获 并没有真正帮助您,反而在您的案例中制造了问题。


如果你想防止这种行为并打印 8,即使属性在闭包内捕获后发生变化,我们也可以使用捕获列表 像这样:

// [calculator] is your capture list
let closure = { [calculator] in
print("The result is \(calculator.sum)")
}
// change anything with calculator instance
calculator.b = 20
// execute the closure
closure() // Prints "The result is 8"

Capture List 保留变量的不可变副本。由于这个副本,在闭包之外对计算器的进一步更改不会影响闭包。

您可以一次捕获多个变量,因此称为捕获列表。示例:

let closure = { [variable1, variable2, variable3] in
print(variable1)
print(variable2)
print(variable3)
}

我推荐你阅读这篇文章 Capturing Values In Swift Closures .



现在,在您的例子中,spotifyClient 是一个可能负责进行 API 调用的类的实例。此实例可能需要一些更改以调用不同的 API。因此,为了防止在这个闭包之外对 spotifyClient 的任何更改的影响,你在 Capture List 中捕获这个实例。



捕获列表与参数列表:

您混淆了参数列表和捕获列表。通用语法是:

{ [capture list] (parameter list) in
...
...
}

现在看看上面例子的修改版本:

let closure: (String)-> Void = { [calculator] stringParameter in // When using single parameter, you can always omit the () parentheses
print("\(stringParameter). The result is \(calculator.sum)")
}

// change anything with calculator instance
calculator.b = 20
// execute the closure
closure("Hey") // Prints "Hey. The result is 8"

关于swift - 带括号的 Swift 中闭包的输入参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49663016/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com