gpt4 book ai didi

swift - 如何在 Swift 中使用类型删除

转载 作者:行者123 更新时间:2023-12-04 08:06:33 25 4
gpt4 key购买 nike

故事:

  • 我有一些布局。
  • 布局具有模式和键。布局可以从这些中发出信息。
  • 每个模式都有最大数量的键。

  • 那是我的表达式模板代码。
    protocol LayoutPattern {
    static var numberOfKeys: Int { get }
    static func make(with keys: [String]) -> String
    }

    struct Pattern1: LayoutPattern {
    static let numberOfKeys: Int = 1
    static func make(with keys: [String]) -> String {
    return "Pattern 1:" + keys.joined(separator: ",")
    }

    let value1: String
    }

    struct Pattern2: LayoutPattern {
    static let numberOfKeys: Int = 2
    static func make(with keys: [String]) -> String {
    return "Pattern 2:" + keys.joined(separator: ",")
    }

    let value1: String
    let value2: String
    }

    protocol LayoutProtocol {
    associatedtype Pattern: LayoutPattern

    var keys: [String] { get }
    func make() -> String
    }

    struct Layout<T: LayoutPattern>: LayoutProtocol {
    typealias Pattern = T

    let keys: [String]
    init(keys: [String]) {
    assert(keys.count == Pattern.numberOfKeys)
    self.keys = keys
    }

    func make() -> String {
    return Pattern.make(with: keys)
    }
    }

    let t1 = Layout<Pattern1>(keys: ["key1"])
    t1.make() // Pattern 1: key1

    let t2 = Layout<Pattern2>(keys: ["key1", "key2"])
    t2.make() // Pattern 2: Key1,Key2
    这是有效的代码。
    但我不能这样写:
    class MyNote {
    let layout: LayoutProtocol
    }
    我知道我应该使用一种叫做类型删除的技术,比如 AnyPokemon!
    我写道:
    struct AnyLayout<T: LayoutPattern>: LayoutProtocol {
    typealias Pattern = T

    let keys: [String]
    private let _make: () -> String

    init<U: LayoutProtocol>(_ layout: U) where T == U.Pattern {
    self.keys = layout.keys
    self._make = { layout.make() }
    }

    func make() -> String {
    _make()
    }
    }

    let anyLayout = AnyLayout(Layout<Pattern2>(keys: ["key1", "key2"]))
    anyLayout.make() // Pattern 2: Key1,Key2
    这可以执行。但是 MyNote 类仍然不能拥有 AnyLayout 的属性。
    我该怎么办?

    最佳答案

    问题是添加了关联类型。它在这里没有做任何工作。没有什么依赖它。删除它,问题就消失了。在您对它们有特定要求之前,不要添加相关类型。
    通常,如果您认为需要类型删除,请先询问您的协议(protocol)是否设计正确。肯定有需要类型橡皮擦的时候,但它们比人们预期的要少得多。
    如果您的算法依赖于 Pattern ,然后展示它,我们可以讨论构建它的方法。 (有许多技术,包括使用多种协议(protocol)。)
    在这里也值得一问 Layout 是否需要通用。你要Layout<Pattern1>Layout<Pattern2> 不同的类型?您然后尝试键入删除它的事实表明您没有。在这种情况下,没有理由使用额外的通用层。在您的示例中, Layout 并没有真正做任何工作。同样,您可能可以摆脱它。让每个模式成为自己的东西,让 Layout 成为将它们与 make() 绑定(bind)的协议(protocol):

    protocol Layout {
    func make() -> String
    }

    struct Pattern1: Layout {
    let key: String
    func make() -> String {
    return "Pattern 1:" + key
    }
    }

    struct Pattern2: Layout {
    let keys: [String]
    init(key1: String, key2: String) {
    keys = [key1, key2]
    }
    func make() -> String {
    return "Pattern 2:" + keys.joined(separator: ",")
    }
    }

    let t1 = Pattern1(key: "key1")
    t1.make() // Pattern 1: key1

    let t2 = Pattern2(key1: "key1", key2: "key2")
    t2.make() // Pattern 2: Key1,Key2

    class MyNote {
    let layout: Layout
    init(layout: Layout) {
    self.layout = layout
    }
    }

    let note = MyNote(layout: t1)
    这使您可以使 Pattern 初始化器的类型更加强大。需要 assert意味着您不会让类型完成工作。通过上述设计,您不能传递错误数量的键。

    关于swift - 如何在 Swift 中使用类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66195029/

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