gpt4 book ai didi

ios - 在 Argo 中解码泛型

转载 作者:搜寻专家 更新时间:2023-10-31 19:38:05 24 4
gpt4 key购买 nike

我正在使用 Thoughtbot 的 Argo 框架将 JSON 对象解析为模型。

我遇到了一个问题,我有这样的协议(protocol)及其扩展

protocol SomeProtocol {
associatedtype Model
func foo()
}

extension SomeProtocol where Model: Decodable {
func foo() -> Model? {
// someJSON is AnyObject in this case, say, from a network call
guard let model: Model = decode(someJSON) else { return nil }
return model
}
}

符合这个协议(protocol)的类看起来像这样

class SomeClass: SomeProtocol {
typealias Model = ArgoModel

func bar() {
print(foo())
}
}

和这样的模型

struct ArgoModel {
let id: String
}

extension ArgoModel: Decodable {
static func decode(j: AnyObject) -> Decoded<ArgoModel> {
return curry(self.init)
<^> j <| "id"
}
}

(我也使用他们的 Curry 库来柯里化(Currying) init 方法)

我遇到的问题是,在 SomeProtocol 扩展中,相关类型 Model 无法被 Argo 解码。我得到的错误是

No 'decode' candidates produced the expected contextual result type 'Self.Model?'

这是 Swift 类型系统的限制吗?还是我遗漏了什么?

最佳答案

在进一步研究之后,这似乎是 Swift 2.3 中 Swift 类型系统的一个限制。该问题的确切原因是上下文类型(如集合和 monad)不符合 Argo 中的 Decodable。所以我的模型只要不包含在集合中就可以工作。使用 Swift 3.0,目标是允许

the ability to make a constrained extension conform to a new protocol (i.e., an array of Equatable elements is Equatable)

如本期所示:https://github.com/thoughtbot/Argo/issues/334

我目前的解决方法是创建一个包含模型数组的复数模型,并在 SomeProtocol 扩展中解码那个。所以现在我的模型看起来像这样:

struct ArgoModels {
let models: [ArgoModel]
}

extension ArgoModels: Decodable {
static func decode(j: JSON) -> Decoded<ArgoModels> {
switch j {
case .Array(let a):
return curry(self.init) <^> sequence(a.map(ArgoModel.decode))
default:
return .typeMismatch("Array", actual: j)
}
}
}

struct ArgoModel {
let id: String
}

extension ArgoModel: Decodable {
static func decode(j: AnyObject) -> Decoded<ArgoModel> {
return curry(self.init)
<^> j <| "id"
}
}

然后在实现类中,我可以创建一个类型别名 Model,它可以是单个对象,也可以是它们的通用集合。

关于ios - 在 Argo 中解码泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36921207/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com