Swift 使用泛型进行快速重构:如何从泛型类型暗示运行时值?

Swift 使用泛型进行快速重构:如何从泛型类型暗示运行时值?,swift,generics,swift3,functional-programming,refactoring,Swift,Generics,Swift3,Functional Programming,Refactoring,我试图在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

我试图在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)
        }
    }
}
func searchFoo(searchText:String?,完成:@escaping([Foo]?,Error?)->()){
let index=“foo”//()){

让index=“bar”/您可以通过创建协议来实现这一点:

protocol Baz {
    static var index: String { get }
    static func loadFromJSON(json: JSONObject) -> [Self]
}
然后扩展
Foo
Bar
以符合此协议。最后,向搜索函数添加通用约束:

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)
        }
    }
}
func搜索(searchText:String?,完成:@escaping([T]?,Error?)->()){
searchClient.search(T.index,searchText){(json,error)在
保护错误==nil else{completion(nil,error!)}
如果让json=json{
完成(Baz.loadFromJSON(json:json),无)
}否则{
完成([],无)
}
}
}

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

protocol Baz {
    static var index: String { get }
    static func loadFromJSON(json: JSONObject) -> [Self]
}
然后扩展
Foo
Bar
以符合此协议。最后,向搜索函数添加通用约束:

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)
        }
    }
}
func搜索(searchText:String?,完成:@escaping([T]?,Error?)->()){
searchClient.search(T.index,searchText){(json,error)在
保护错误==nil else{completion(nil,error!)}
如果让json=json{
完成(Baz.loadFromJSON(json:json),无)
}否则{
完成([],无)
}
}
}

也许可以尝试将方法重写为尽可能通用的方法,只需保留您实际问题所在的位置。现在,我花了相当长的时间来理解泛型在这里的用途。现在我的问题是,特别是您如何考虑处理
fooFrom
barFrom
,因为它们不是通用的neric。关于获取泛型类型的名称可能会有帮助。好的一点。我将编辑@Tim的答案以反映这一点。也许尝试将方法重写为尽可能泛型的方法,只需保留您实际问题所在的部分。现在我花了相当长的时间来理解泛型在这里的用途。现在我的问题特别是你如何看待处理
fooFrom
barFrom
,因为它们根本不是泛型的。关于获取泛型类型的名称可能是有帮助的。我将编辑@Tim的答案以反映这一点。