CS193P SwiftUI 2020任务3-作为函数参数的闭包
我正在学习Paul Hegarty的CS193P 2020课程,作业3要求我们使用闭包作为函数的参数。这是我们在上一节课中已经做过的事情,对我来说很清楚(事实上我认为是的)。 在我自己尝试之后,我终于在这里找到了解决方案:它工作得很好,但我仍然很难理解发生了什么 下面是SetGame init使用闭包创建CardContent的模型代码CS193P SwiftUI 2020任务3-作为函数参数的闭包,swift,mvvm,swiftui,closures,Swift,Mvvm,Swiftui,Closures,我正在学习Paul Hegarty的CS193P 2020课程,作业3要求我们使用闭包作为函数的参数。这是我们在上一节课中已经做过的事情,对我来说很清楚(事实上我认为是的)。 在我自己尝试之后,我终于在这里找到了解决方案:它工作得很好,但我仍然很难理解发生了什么 下面是SetGame init使用闭包创建CardContent的模型代码 struct SetGame { var deck: [Card] init(cardContentFactory: (Int, Ca
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))
}
}
}
}
}
}
在ViewModel中:
class SetGameViewModel: ObservableObject {
private var setModel: SetGame
init() {
setModel = SetGame() {
CardContent(number: $0, shape: $1, shading: $2, color: $3)
}
print(setModel.deck)
}
}
关于此代码,我有两个问题:
- 我不明白这行
是如何工作的,因为在我看来它似乎没有传递任何“实际”数据。在上一节课中,保罗使用的例子是传输真实数据。下面是使用的代码,它清楚地传递了冲浪者表情符号CardContent(数字:$0,形状:$1,阴影:$2,颜色:$3)
func createMemoryGame() -> MemoryGame<String> { return MemoryGame<String>(numberOfPairsOfCards: 2) { _ in "
setModel = SetGame() { CardContent(number: $0, shape: $1, shading: $2, color: $3) }
忽略返回到闭包中的数据。将下划线替换为func createMemoryGame()->MemoryGame{ 返回存储器名称(卡的对数:2){in“ 这里我们使用一个尾随闭包。相反,您可以将其编写为:
因此,我们将数据传递给SetGame.init(cardContentFactory:)方法:我们将传递一个闭包,该闭包稍后接受4个参数的值 < <代码> > 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)" })
在这里,
是一个很长的说法“lowercase it”,因此{string in return string.lowercased()}
表示“it”。$1、$2等表示第二个、第三个参数。同样,必须创建和命名函数(如$0
也是使用匿名(未命名)的很长一段路闭包。据我所知,我们可以通过闭包直接传递值,或者稍后使用$x来管理值?您传递的是一个函数,也称为闭包,进入SetGame.init(cardContentFactory:)方法创建一个新的SetGame,并将此函数烘焙到其中。现在,每当SetGame想要制作一张新卡时,它都会使用此函数制作该卡的内容。$0、$1等表示在调用函数制作新卡时从SetGame传递到“卡内容工厂”函数的值此函数on是SetGame的一个参数,所以你可以修改它。你可以传入一些其他函数来制作一种不同的SetGame,它仍然使用SetGame的相同逻辑,但制作的卡片内容不同。每当它制作卡片时,非常感谢你的回答,这对我来说是有意义的。这是一大步,因为它是基础Swift.in的所有方面。在第二组代码中,doubleString(:)
,如果将其全部删除,您现在可以读取它。您可以使用值
读取它。$0,$1等是顺序中的返回值,而不实际定义它们$0
中的(数字、形状、阴影、颜色)将实际定义返回值,您可以替换SetGame(){
CardContent
中相应的init
,谢谢,我将用SetGame()测试另一种方法{(数字、形状、阴影、颜色)}在我看来,这更符合通用方法以及Model和ViewModel各自的角色。不要将结束括号放在该行的末尾。在$n
CardContent
之后结束。您需要做的任何事情都必须在这些括号之间,并最终init
谢谢您的帮助,我想我终于明白了。我将在我的代码中检查它。返回汽车dContent(…)
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)" })