如何使用 Swift 从一个函数返回不同类型的结构?

Posted

技术标签:

【中文标题】如何使用 Swift 从一个函数返回不同类型的结构?【英文标题】:How to make possible to return structs of different types from one function with Swift? 【发布时间】:2022-01-10 10:12:57 【问题描述】:

我有这个功能:

 class func cURL (urlT: String, Completion block: @escaping ((Profile) -> ())) 
        
        GetJson.loadJsonFromUrl(fromURLString: urlT)  (result) in
            switch result 
            case .success(let data):
                    
                //Parse
                if let decodedJson = GetJson.ParseJson(jsonData: data) 
                    block(decodedJson)
                
                
                
            case .failure(let error):
                print("loadJson error:", error)
            
        
    

这就是 ParseJson 函数,可能也要修改:

 class func ParseJson(jsonData: Data) -> Profile? 
        do 
            let decodedData = try JSONDecoder().decode(Profile.self, from: jsonData)
            return decodedData
         catch 
            print("decode error: ",error)
        
        return nil
    

如何根据接收到的 url 类型更改 cURL 函数以返回不同类型的结构?

我这样称呼 cURL:

cURL(urlT: encodedUrl)  (Json) in print(Json) 

例如,我给 cURL 一个 url1,它返回一个 Profile 类型的 Json。 我尝试做的是,如果我给出一个 url2,我希望它返回一个 profile2 类型的 Json。

我尝试使用带类型的枚举,但无法正常工作。 你能帮忙的话,我会很高兴。谢谢。

【问题讨论】:

您应该考虑使用泛型,这是泛型的常见用例,因此找到合适的教程/文章应该不难 【参考方案1】:

我花了一整夜,但我找到了使用泛型的解决方案:

class JSONParser 
    
    typealias result<T> = (Result<T, Error>) -> Void
    
    class func cURL2<T: Decodable>(of type: T.Type,
                             from url: String,
                             Completion block: @escaping ((Any) -> ()) ) 
        
        download(of: T.self, from: url)  (result) in
            switch result 
                
            case .failure(let error):
                print(error)
            case .success(let response):
                block(response)
            
        
    
    
    class func download<T: Decodable>(of type: T.Type,
                                    from urlString: String,
                                    completion: @escaping result<T>) 
        
            guard let url = URL(string: urlString) else return
            URLSession.shared.dataTask(with: url)  (data, response, error) in
                if let error = error 
                    print(error)
                    completion(.failure(error))
                
                
                if let data = data 
                    do 
                        let decodedData: T = try JSONDecoder().decode(T.self, from: data)
                        completion(.success(decodedData))
                    
                    catch 
                        print("decode error: ",error)
                    
                
            .resume()
        


JSONParser.cURL2(of: Profile.self, from: url1) (Json) in
    print(Json)

【讨论】:

以上是关于如何使用 Swift 从一个函数返回不同类型的结构?的主要内容,如果未能解决你的问题,请参考以下文章

Swift:从函数返回类型 JSON

Delphi - 如何从函数返回不同的类型

如何将不同类型的结构体作为一个函数的参数?

如何从不同的swift文件访问一个类中的所有对象

swift中泛型和 Any 类型

如何从存储在 Firestore (Swift) 中的文档中返回对象