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

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

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

问题

Here is the translation of the code you provided:

  1. 我有一个名为`UISectionModel`的结构体,只有一个名为`section`的属性,该属性遵循一个名为`UISectionProtocol`的协议,如下所示:
  2. ```swift
  3. struct UISectionModel: Codable {
  4. let section: UISectionProtocol
  5. }

这是UISectionProtocol协议的实现:

  1. protocol UISectionProtocol: Codable {
  2. var identifier: String? { get }
  3. }

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

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

  1. struct UISectionModel: Codable {
  2. let section: UIDefaultSection
  3. }
  4. enum UIDefaultSection: UISectionProtocol {
  5. case imageSection(section: UIImageSection)
  6. case labelSection(section: UILabelSection)
  7. var identifier: String? {
  8. switch self {
  9. case .imageSection(let section): return section.identifier
  10. case .labelSection(let section): return section.identifier
  11. }
  12. }
  13. }

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

  1. <details>
  2. <summary>英文:</summary>
  3. 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
}

  1. Here is the implementation of the `UISectionProtocol` protocol:

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

  1. 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.
  2. Would appreciate some insight!
  3. 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)

  1. var identifier: String? {
  2. switch self {
  3. case .imageSection(let section): return section.identifier
  4. case .labelSection(let section): return section.identifier
  5. }
  6. }

}

  1. 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`.
  2. </details>
  3. # 答案1
  4. **得分**: 2
  5. 我认为问题在于您可能认为以下代码段:
  6. ```swift
  7. protocol UISectionProtocol: Codable

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

  1. struct SectionModel<T: SectionProtocol>: Codable {
  2. let section: T
  3. }
  4. protocol SectionProtocol: Codable {
  5. var identifier: String? { get }
  6. }

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

英文:

I think the problem is that you probably believe that saying

  1. 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:

  1. struct SectionModel&lt;T: SectionProtocol&gt;: Codable {
  2. let section: T
  3. }
  4. protocol SectionProtocol: Codable {
  5. var identifier: String? { get }
  6. }

(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 的。以下是你代码的更新版本,我认为这可能会解决你的问题。

  1. protocol UISectionProtocol: Codable {
  2. var identifier: String? { get }
  3. }
  4. struct UISectionModel<T: UISectionProtocol>: Codable where T: Codable {
  5. let section: T
  6. }
  7. struct MySection: UISectionProtocol, Codable {
  8. var identifier: String?
  9. }
英文:

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.

  1. protocol UISectionProtocol: Codable {
  2. var identifier: String? { get }
  3. }
  4. struct UISectionModel&lt;T: UISectionProtocol&gt;: Codable where T: Codable {
  5. let section: T
  6. }
  7. struct MySection: UISectionProtocol, Codable {
  8. var identifier: String?
  9. }

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:

确定