【问题标题】:A type mismatch issue with generic methods泛型方法的类型不匹配问题
【发布时间】:2021-04-25 23:08:14
【问题描述】:

我遇到了一个问题,我认为与其试图解释,不如展示它会更有效。

我有这段代码,当我运行它时会打印出来

struct One: Codable {}
struct Two: Codable {}

func test<T: Codable>(ofType: T.Type) {
    print(ofType)
}

var array = Array<Codable.Type>()

array.append(One.self)
array.append(Two.self)

array.forEach { (type) in
    print(type)
} // Outs: One\nTwo

test(ofType: One.self) // out: One
test(ofType: Two.self) // out: Two

但是当我试图说;

array.forEach { (type) in
    test(ofType: type)
}

它抛出

Cannot convert value of type 'Codable.Type' (aka '(Decodable & Encodable).Type') to expected argument type 'T.Type'

添加test(ofType: type as! T.Type) 会相应地为forEachtest 本身抛出这些

Type of expression is ambiguous without more context
Cannot find type 'T' in scope

由于令牌刷新,我正在尝试实现这一点。当令牌刷新时,我缓存具有相关类型的请求,响应将被解析为。

private static var cachedRequests: [(Endpoint, Decodable.Type)]
class func makeRequest<T: Decodable>(to endpoint: Endpoint, decodeAsWrapped type: T.Type, completion: @escaping (Result<T, Error>) -> Void)

有什么建议吗?

编辑

我想补充一个奇怪的东西如下:

func test<T: Codable>(ofType: T.Type) {
    array.append(ofType)
}

以上代码运行良好。我可以将ofType 附加到一个数组,但是不能使用该精确数组中的任何项目作为ofType 的输入。对我来说非常出乎意料的事情。

【问题讨论】:

  • 集合中的所有元素都应该是相同的通用 Codable 类型。如果您希望能够在同一个集合中添加不同的类型,那么您就走错了路。这不是泛型的用途。
  • 试过了,还是不行。我认为首先不可能追加。
  • 将响应保留为数据
  • 无需为您的测试方法使用泛型类型func test(ofType: Codable.Type) { print(ofType) }
  • [Codable] 不是一个明智的类型。你不能谈论“可以从数据中解码的未知类型”。这是非常模棱两可的。只要有正确的规则,任意数据都可以解码为几乎任何东西。但我认为你真正想要构建的是[Encodable],这是一个明智的类型。 Swift 只是目前不支持它。如果您能解释您要解决的问题,那么我们可能会提供帮助。凌乱的类型橡皮擦AnyEncodable 很容易构建。只是 Swift 不应该需要它,但确实需要它。 (目前论坛上正在讨论改进这一点。)

标签: swift generics


【解决方案1】:

这是你想要的吗?

struct One: Codable {}
struct Two: Codable {}

func test(ofType: Codable.Type) {
    print(ofType)
}

var array = Array<Codable.Type>()

array.append(One.self)
array.append(Two.self)

array.forEach { (type) in
    print(type)
} // Outs: One\nTwo

test(ofType: One.self) // out: One
test(ofType: Two.self) // out: Two

array.forEach { (type) in
    test(ofType: type)
} // Outs: One\nTwo

【讨论】:

  • 所以只要让test 方法不通用就可以了。由于makeRequest 的完成取决于泛型类型,我认为这不会直接起作用。我通过不缓存请求对象和目标解码类型而是缓存代码块本身解决了这个问题。但是,由于这解决了我给出的示例,我想我应该接受这个答案。谢谢@AnderCover
  • 如果缓存是问题,我不确定您所说的“缓存代码块本身”是什么意思,根据我的经验,缓存Data 并让查询特定缓存的代码更简单item 担心解码错误
  • 是的,但这种情况特别是在刷新令牌时缓存请求。我已经编写了代码,这样它就不会等待任何401 作为响应。所以在我现在的情况下,实际上没有Data。但是,是的,由于某种解码失败而缓存请求我会按照您建议的方式进行
猜你喜欢
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 2020-10-18
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多