swift - CS193P SwiftUI 2020 作业 3 - 闭包作为函数参数
问题描述
我正在关注 Paul Hegarty 的 CS193P 2020 课程,作业 3 要求我们使用闭包作为函数的参数。这是我们在之前的讲座中已经做过的事情,这对我来说很清楚(事实上我认为是这样)。在自己尝试之后,我终于在这里找到了解决方案:https ://github.com/marlen-myn/set-game ,它工作正常,但我仍然很难理解发生了什么。
这是带有 SetGame init 的模型代码,它使用闭包来创建 CardContent。
struct SetGame {
var deck: [Card]
init(cardContentFactory: (Int, CardShape, CardShading, CardColor) -> CardContent) {
deck = [Card]()
for number in 1...3 {
for shape in CardShape.allCases {
for shading in CardShading.allCases {
for color in CardColor.allCases {
let content = cardContentFactory(number, shape, shading, color)
deck.append(Card(id: deck.count, content: content))
}
}
}
}
}
}
在视图模型中:
class SetGameViewModel: ObservableObject {
private var setModel: SetGame
init() {
setModel = SetGame() {
CardContent(number: $0, shape: $1, shading: $2, color: $3)
}
print(setModel.deck)
}
}
关于这段代码,我有两个问题:
我不明白这条线是如何
CardContent(number: $0, shape: $1, shading: $2, color: $3)
工作的,因为在我看来它没有传递任何“实际”数据。在上一课中,Paul 使用的示例是传输真实数据。这是使用的代码,它清楚地通过了冲浪者表情符号func createMemoryGame() -> MemoryGame<String> { return MemoryGame<String>(numberOfPairsOfCards: 2) { _ in "♂️" }}
在我看来,没有真正需要这样做(关闭)。是因为它做得不对(即使它有效)还是因为它真的没用。
谢谢你的帮助,我真的很想理解这一点,因为我知道闭包在 Swift 中无处不在,也因为我讨厌做一些我不理解的事情,即使它有效。
解决方案
setModel = SetGame() {
CardContent(number: $0, shape: $1, shading: $2, color: $3)
}
所以在这里我们使用尾随闭包。相反,您可以将其写为:
SetGame.init(cardContentFactory: { CardContent(number: $0, shape: $1, shading: $2, color: $3) } )
因此,我们将数据传递给 SetGame.init(cardContentFactory:) 方法:我们传递了一个闭包,该闭包稍后会接收 4 个参数的值。
On $0
, $1
, $2
- 这些代表代词,函数的参数。这些有用的原因是简洁:例如,考虑这个游乐场:
func changeThings(how f: (String) -> String) -> [String] {
let things: [String] = ["A", "B", "C", "D"]
var result: [String] = []
for thing in things {
result.append(f(thing))
}
return result
}
let lc1 = changeThings(how: { string in return string.lowercased() })
let lc2 = changeThings(how: { $0.lowercased() })
func doubleString(_ s: String) -> String {
return "\(s)\(s)"
}
let db1 = changeThings(how: doubleString(_:))
let db2 = changeThings(how: { "\($0)\($0)" })
“小写{ string in return string.lowercased() }
它”的说法很长,所以$0
意思是“它”。$1, $2 等用于第二个,第三个参数。类似地,必须创建和命名函数(就像doubleString(_:)
只使用匿名(未命名)闭包一样很长的路要走。
推荐阅读
- hive - 如何在 apache hive 中插入日期、布尔值?
- python - 我怎样才能以不同的方式编写它,以便不总是调用夹具?
- svn - Trac 可以从其他服务器连接到 SVN 存储库吗?
- javascript - 使用 RegExp 提取特定字符串
- angular - appendComponentToBody 在角度 2 中不起作用
- kubernetes - 如何在 kubernetes 中为服务端点 url 使用服务名称而不是外部 IP/域名
- angularjs - md-datepicker 不适用于引导模式,而适用于 angularjs 中的简单页面
- codeigniter - 如何从第一个结果数组中检查名称是否已存在
- python - 如何使用 GridFSBucket 逐块处理正在下载的文件
- node.js - 节点需要 - 我不明白这段代码