[英]Input parameter to closure in Swift with brackets
I am going through the following tutorial on RxSwift
: 我将在RxSwift
上RxSwift
以下教程:
http://adamborek.com/thinking-rxswift/ http://adamborek.com/thinking-rxswift/
and having trouble understanding the following pattern: 并且无法理解以下模式:
searchBar.rx.text.orEmpty
------------> .flatMap { [spotifyClient] query in
return spotifyClient.rx.search(query: query)
}.map { tracks in
return tracks.map(TrackRenderable.init)
}
This square brackets input parameter: [spotifyClient] query
seems very weird for me. 这个方括号输入参数: [spotifyClient] query
对我来说似乎很奇怪。 I looked over official Apple
documentation for closures and functions and I can not see any examples of such input parameters. 我查看官方Apple
文档中的闭包和函数,我看不到这些输入参数的任何示例。 In Objective C
this would not bother me much, but it is Swift
. 在Objective C
这不会让我感到烦恼,但它是Swift
。 Could anyone explain, what this parameter means here? 谁能解释一下,这个参数在这里意味着什么?
You will need to understand the variable capturing of closure idea. 您需要了解闭包概念的变量捕获 。
struct Calculator {
var a: Int
var b: Int
var sum: Int {
return a + b
}
}
Then you use this as: 然后你用它作为:
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"
Till now, everything is okay. 直到现在,一切都还好。 You get what's expected. 你得到了预期的结果。
Now consider you declare the calculator instance as var
because in some point you need to mutate it's state. 现在考虑将计算器实例声明为var
因为在某些时候你需要改变它的状态。 This is the case where complexity arises. 这就是出现复杂性的情况。 Look: 看:
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"
So, the default variable capture isn't really helping you, instead it's creating problem in your case. 因此, 默认变量捕获并不能真正帮助您,而是在您的情况下创建问题。
If you want to prevent this behaviour and print 8 even if the properties change after their capturing inside the closure, we can explicitly capture the variable with a capture list like this: 如果你想阻止这种行为并打印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 keeps immutable copy of the variable(s). 捕获列表保留变量的不可变副本。 Thanks to this copy, further changes to calculator, outside the closure, will not affect the closure. 由于这个副本,在闭包之外对计算器的进一步更改不会影响关闭。
You can capture multiple variables at once, hence it's called Capture List . 您可以一次捕获多个变量,因此称为捕获列表 。 Example: 例:
let closure = { [variable1, variable2, variable3] in
print(variable1)
print(variable2)
print(variable3)
}
I recommend you read this article Capturing Values In Swift Closures . 我建议你阅读这篇文章在Swift Closures中捕获值 。
Now, in your case spotifyClient
is an instance of a class that may be responsible to make API calls. 现在,在您的情况下, spotifyClient
是一个可能负责进行API调用的类的实例。 This instance may need some changes for calling different APIs. 此实例可能需要进行一些更改以调用不同的API。 So, to prevent the affect of any changes to spotifyClient
outside this closure you capture this instance in a Capture List . 因此,为了防止对此闭包外的spotifyClient
进行任何更改的影响,您可以在捕获列表中捕获此实例。
You are confusing the parameter list with the capture list. 您将参数列表与捕获列表混淆。 The generic syntax is: 通用语法是:
{ [capture list] (parameter list) in
...
...
}
Now take a look at the modified version of the above example: 现在来看看上面例子的修改版本:
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"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.