Struct with protocol as property type does not conform to protocols ‘Decodable’ and ‘Encodable’.

huangapple go评论77阅读模式
英文:

Struct with protocol as property type does not conform to protocols 'Decodable' and 'Encodable'

问题

Here is the translation of the code you provided:

我有一个名为`UISectionModel`的结构体,只有一个名为`section`的属性,该属性遵循一个名为`UISectionProtocol`的协议,如下所示:

```swift
struct UISectionModel: Codable {
    let section: UISectionProtocol
}

这是UISectionProtocol协议的实现:

protocol UISectionProtocol: Codable {
    var identifier: String? { get }
}

正如您所看到的,我需要让UISectionModel遵循Codable协议,但我一直收到一个错误,指出它既不遵循Decodable也不遵循Encodable,尽管唯一的属性类型已经遵循了Codable。我怀疑这与这个类型是一个协议有关,但我无法确定导致错误出现的确切原因或如何修复它。

我尝试将section的类型替换为符合UISectionProtocol的枚举:

struct UISectionModel: Codable {
    let section: UIDefaultSection
}

enum UIDefaultSection: UISectionProtocol {
    case imageSection(section: UIImageSection)
    case labelSection(section: UILabelSection)
    
    var identifier: String? {
        switch self {
        case .imageSection(let section): return section.identifier
        case .labelSection(let section): return section.identifier
        }
    }
}

这使错误消失了,但我在思考section是否需要是符合UISectionProtocol的任何类型,而不仅仅限于UIDefaultSection


<details>
<summary>英文:</summary>

I have a struct `UISectionModel` with only one property `section`, which has a protocol `UISectionProtocol` for a type, as follows:

struct UISectionModel: Codable {
let section: UISectionProtocol
}

Here is the implementation of the `UISectionProtocol` protocol:

protocol UISectionProtocol: Codable {
var identifier: String? { get }
}

As you can see, I need `UISectionModel` to conform to the `Codable` protocol, but I keep getting an error stating that it does not conform to neither `Decodable` or `Encodable`, even though the only property&#39;s type is already conforming to `Codable`. I suspect it has to do with the fact that this type is a protocol, but I can&#39;t figure the exact reason that is causing the error to appear or how to fix it. 

Would appreciate some insight!

I tried replacing the type of `section` with an enum that conforms to `UISectionProtocol`:

struct UISectionModel: Codable {
let section: UIDefaultSection
}

enum UIDefaultSection: UISectionProtocol {
case imageSection(section: UIImageSection)
case labelSection(section: UILabelSection)

var identifier: String? {
    switch self {
    case .imageSection(let section): return section.identifier
    case .labelSection(let section): return section.identifier
    }
}

}

This made the error go away, but I&#39;m thinking that `section` needs to be of any type that conforms to `UISectionProtocol`, instead of being limited only to `UIDefaultSection`.


</details>


# 答案1
**得分**: 2

我认为问题在于您可能认为以下代码段:

```swift
protocol UISectionProtocol: Codable

意味着UISectionProtocol符合Codable。但实际上它并不符合。协议不会符合协议。您可能想要一个泛型:

struct SectionModel<T: SectionProtocol>: Codable {
    let section: T
}

protocol SectionProtocol: Codable {
    var identifier: String? { get }
}

(请注意,我已经去掉了您的类型名称中非法的UI前缀;该前缀仅属于Apple。)

英文:

I think the problem is that you probably believe that saying

protocol UISectionProtocol: Codable 

means that UISectionProtocol conforms to Codable. it doesn't. A protocol does not conform to a protocol. You probably want a generic:

struct SectionModel&lt;T: SectionProtocol&gt;: Codable {
    let section: T
}

protocol SectionProtocol: Codable {
    var identifier: String? { get }
}

(Note that I have stripped the illegal UI prefix off your type names; that prefix belongs to Apple alone.)

答案2

得分: 1

你遇到的问题是由不符合 Codable 协议的协议引起的。当你在 UISectionModel 结构体中包含一个 UISectionProtocol 字段时,编译器无法保证所有符合类型也都是 Codable 的。

要解决这个问题,你可以将 UISectionModel 定义为泛型,并添加一个类型约束以确保 section 属性也是 Codable 的。以下是你代码的更新版本,我认为这可能会解决你的问题。

protocol UISectionProtocol: Codable {
    var identifier: String? { get }
}

struct UISectionModel<T: UISectionProtocol>: Codable where T: Codable {
    let section: T
}

struct MySection: UISectionProtocol, Codable {
    var identifier: String?
}
英文:

The issue you experienced is caused by protocols that don't conform to Codable. When you include a UISectionProtocol field in your UISectionModel struct, the compiler cannot guarantee that all conforming types are also Codable.
To fix this problem you can make UISectionModel generic and add a type constraint to ensure the section property is also codable. Here is an updated version of your code. I think this may solve your issue.

protocol UISectionProtocol: Codable {
    var identifier: String? { get }
}
struct UISectionModel&lt;T: UISectionProtocol&gt;: Codable where T: Codable {
    let section: T
}

struct MySection: UISectionProtocol, Codable {
    var identifier: String?
}

huangapple
  • 本文由 发表于 2023年6月12日 10:02:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76453259.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定