首页 > 解决方案 > 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)
    }
}

关于这段代码,我有两个问题:

谢谢你的帮助,我真的很想理解这一点,因为我知道闭包在 Swift 中无处不在,也因为我讨厌做一些我不理解的事情,即使它有效。

标签: swiftmvvmswiftuiclosures

解决方案


        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(_:)只使用匿名(未命名)闭包一样很长的路要走。


推荐阅读