【问题标题】:How to make a Swift Enum with Associated values conform to Codable?如何使具有关联值的 Swift 枚举符合 Codable?
【发布时间】:2021-07-22 22:37:53
【问题描述】:

我会在具有可编码协议的结构中使用枚举。但我不知道,很高兴为枚举制作一个init。如果我没有init,编译器会引发错误。

这里的目标是UpdateIn类型中的value参数可以是两个东西,一个字符串或者一个FormFiled结构。

你知道怎么做这个初始化吗?

struct UpdateIn: Content {
    var keyPath: [String]
    var value: Value
    var operation: String
}

enum Value: Decodable {
    init(from decoder: Decoder) throws {
        <#code#>
    }
    
  case str(String)
  case formField(FormField)
}

struct FormField: Content {
    var name: String
    var type: String
    var options: [String: FormFieldOption]?
    var selectedOption: String?
    var visibleIfIndIsVisible: Int?
    var ind: Int
    var mandatory: Bool // TODO: isMandatory
    var dateCreatedAt: Date?
    var selectItemOtherArbitraryValueEnable: Bool?
    var regex: String?
    var hasImage: Bool?
    var defaultFormFieldOptionId: String?
}

根据回答我尝试提取值并分配给特定变量,但被拒绝,你知道为什么吗?

let formField: FormField = params.value

无法将“Value”类型的值转换为指定类型“FormField”

【问题讨论】:

  • 这取决于您的数据是什么样的。最终你只是分配给自己,要么self = .string(someStringValue)self = .formField(someFormField)

标签: swift enums codable


【解决方案1】:

你只需要切换你的枚举关联值:

enum Value: Codable {
    case str(String)
    case formField(FormField)
    private enum CodingKeys: String, CodingKey {
        case str, formField
    }
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        switch self {
        case let .str(string):
            try container.encode(string, forKey: .str)
        case let .formField(field):
            try container.encode(field, forKey: .formField)
        }
    }
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        switch container.allKeys.first {
        case .str:
            self = try .str(container.decode(String.self, forKey: .str))
        case .formField:
            self = try .formField(container.decode(FormField.self, forKey: .formField))
        default:
            throw DecodingError.dataCorrupted(
                .init(
                    codingPath: container.codingPath,
                    debugDescription: "invalid data"
                )
            )
        }
    }
}

【讨论】:

  • 谢谢,如何获取价值,参考价值?我试过:value.formField 但编译器说:Cannot assign value of type '(FormField) -&gt; Value' to subscript of type 'FormField'
  • @János 不确定您在哪里收到此错误。随意编辑您的帖子并展示您尝试过的内容以及您面临的问题。请注意,您没有发布 FormFieldOption 声明。请提供minimal reproducible example
  • 您需要切换您的值,它可以是字符串或FormField。检查编码开关语法
  • switch params.value { case let .str(string): print(string) case let .formField(field): print(field) }
  • 你会在这里检查这个吗?被困。 stackoverflow.com/questions/68509201/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2017-08-19
相关资源
最近更新 更多