繁体   English   中英

如何在通用函数中使用 swift 通用可解码协议

[英]How do I use swift generic Decodable protocol in generic functions

我想编写一个通用函数来解析结果并在关闭的成功块中返回或在失败块中发回错误。

我收到这样的错误'Generic parameter 'T' could not be inferred'

这是我的示例代码。

let jsonString = """
{
"id": 1,
"msg": "Sample msg"
}
"""

struct Post: Codable {
    var id: String?
    var msg: String?
}

enum PostError: Error {
    case empty
}


func fetch<T:Decodable>(_ completion: @escaping (Result<T?, PostError>) -> Void)  {

        do {
            let data = Data(jsonString.utf8)
            let post = try JSONDecoder().decode(T.self, from: data)
            completion(.success(post))
        }
        catch {
            completion(.failure(.empty))
        }
    }


fetch { res in
        switch res {
        case .success( let p):
            print(p.description)

        case .failure(let error):
            print(error)
        }
    }

这是我得到的错误。

我收到这样的错误。

您可以接受泛型类型作为参数,如下所示:

func fetchObject<T:Decodable>(ofType type: T.Type, _ completion: @escaping (Result<T, PostError>) -> Void)  {
   do {
      let data = Data(jsonString.utf8)
      let post = try JSONDecoder().decode(type, from: data)
      completion(.success(post))
   }
   catch {
      completion(.failure(.empty))
   }
}

用法:

fetchObject(ofType: Post.self) { res in
   switch res {
       case .success(let post):
          print(post.description)
       case .failure(let error):
          print(error)
   }
}

我了解您要做什么,但主要问题是您从未指定类型。 编译器知道您要调用fetch但它不知道您要获取什么或将其解析为什么。

如果您查看您的fetch调用,编译器可能无法告诉您正在尝试做什么或您希望发生什么。

你要么必须:

1. 将类型作为参数传递

func fetch<T: Decodable>(_ type: T.Type, _ completion: @escaping (Result<T, PostError>) -> Void)  {

    do {
        let data = Data(jsonString.utf8)
        let post = try JSONDecoder().decode(T.self, from: data)
        completion(.success(post))
    }
    catch {
        completion(.failure(.empty))
    }
}


fetch(Post.self) { res in
        switch res {
        case .success(let p):
            print(p)

        case .failure(let error):
            print(error)
        }
    }

或者...

2. 在实例化该函数所属的对象时指定类型:

struct Fetcher<T: Decodable> {

    func fetch(_ completion: @escaping (Result<T, PostError>) -> Void)  {

        do {
            let data = Data(jsonString.utf8)
            let post = try JSONDecoder().decode(T.self, from: data)
            completion(.success(post))
        }
        catch {
            completion(.failure(.empty))
        }
    }
}

let fetcher = Fetcher<Post>()
fetcher.fetch { res in
    switch res {
    case .success(let p):
        print(p)

    case .failure(let error):
        print(error)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM