【问题标题】:Swift refactor with generics: how can I imply runtime values from the generic type?使用泛型进行 Swift 重构:如何从泛型类型中暗示运行时值?
【发布时间】:2017-08-14 11:28:42
【问题描述】:

我正在尝试在 Swift 中使用泛型分解方法。我的方法如下:

func searchFoo(searchText: String?, completion: @escaping ([Foo]?, Error?) -> ()) {
    let index = "foo" // <- How can I assign this from a generic type?
    searchClient.search(index, searchText) { (json, error) in
        if let json = json {
            completion(self.fooFrom(json: json), nil)
        } else if let error = error {
            completion(nil, error)
        } else {
            completion([], nil)
        }
    }
}

func searchBar(searchText: String?, completion: @escaping ([Bar]?, Error?) -> ()) {
    let index = "bar" // <- How can I assign this from a generic type?
    searchClient.search(index, searchText) { (json, error) in
        if let json = json {
            completion(self.barFrom(json: json), nil)
        } else if let error = error {
            completion(nil, error)
        } else {
            completion([], nil)
        }
    }
}

这 2 个函数看起来像是泛型的一个很好的用例,但我不知道如何打开泛型类型来获取 2 个必需的字符串。

当然,我可以将索引名称放在函数签名中,但我觉得这将是多余的,因为索引名称隐含在实际使用的泛型类型中,并且可能是错误的来源。

我觉得我遗漏了一些东西,因为我可能还没有思考 Swift 的方式,所以欢迎任何帮助来获得对这段代码的良好重构。

【问题讨论】:

  • 也许可以尝试尽可能通用地重写该方法,并在您的实际问题所在的地方留下一点。现在,我花了相当长的时间来理解泛型在这里的用处。现在我的问题特别是您如何看待处理fooFrombarFrom,因为它们根本不是通用的。关于获取泛型类型的名称this可能会有所帮助
  • 好点。我将编辑@Tim 的答案以反映这一点。

标签: swift generics swift3 functional-programming refactoring


【解决方案1】:

您可以通过创建协议来实现:

protocol Baz {
    static var index: String { get }
    static func loadFromJSON(json: JSONObject) -> [Self]
}

然后扩展FooBar 以符合此协议。最后,为您的搜索功能添加一个通用约束:

func search<T: Baz>(searchText: String?, completion: @escaping ([T]?, Error?) -> ()) {
    searchClient.search(T.index, searchText) { (json, error) in
        guard error == nil else { completion(nil, error!) }

        if let json = json {
            completion(Baz.loadFromJSON(json: json), nil)
        } else {
            completion([], nil)
        }
    }
}

【讨论】:

    猜你喜欢
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多