如何在可编码结构中使用计算属性(swift)

Posted

技术标签:

【中文标题】如何在可编码结构中使用计算属性(swift)【英文标题】:How to use computed property in a codable struct (swift) 【发布时间】:2018-08-24 21:01:04 【问题描述】:

我创建了一个“可编码”结构来序列化数据集并将其编码为 Json。除了计算的属性没有显示在 json 字符串中之外,一切都很好。如何在编码阶段包含计算属性。

例如:

struct SolidObject:Codable

    var height:Double                      = 0
    var width:Double                       = 0
    var length:Double                      = 0

    var volume:Double 
        get
            return height * width * length
        
    


var solidObject = SolidObject()
solidObject.height = 10.2
solidObject.width = 7.3
solidObject.length = 5.0

let jsonEncoder = JSONEncoder()
do 
    let jsonData = try jsonEncoder.encode(solidObject)
    let jsonString = String(data: jsonData, encoding: .utf8)!
    print(jsonString)
 catch 
    print(error)

打印出 ""width":7.2999999999999998,"length":5,"height":10.199999999999999"

我也很好奇有 7.29999.. 而不是 7.3,但我的主要问题是“我怎样才能在这个 json 字符串中也包含“音量”?

【问题讨论】:

【参考方案1】:

您需要手动编码/解码,而不是让自动化的东西为您完成。这在 Swift 操场上按预期工作。

struct SolidObject: Codable 

    var height:Double                      = 0
    var width:Double                       = 0
    var length:Double                      = 0

    var volume:Double 
        get
            return height * width * length
        
    

    enum CodingKeys: String, CodingKey 
        case height
        case width
        case length

        case volume
    

    init()  

    init(from decoder: Decoder) throws 
        let values = try decoder.container(keyedBy: CodingKeys.self)
        height = try values.decode(Double.self, forKey: .height)
        width = try values.decode(Double.self, forKey: .width)
        length = try values.decode(Double.self, forKey: .length)
    

    func encode(to encoder: Encoder) throws 
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(height, forKey: .height)
        try container.encode(width, forKey: .width)
        try container.encode(length, forKey: .length)

        try container.encode(volume, forKey: .volume)
    



var solidObject = SolidObject()
solidObject.height = 10.2
solidObject.width = 7.3
solidObject.length = 5.0

let jsonEncoder = JSONEncoder()
do 
    let jsonData = try jsonEncoder.encode(solidObject)
    let jsonString = String(data: jsonData, encoding: .utf8)!
    print(jsonString)
 catch 
    print(error)

【讨论】:

谢谢...你能解释一下那里的空初始化块吗?怎么不会引起“var solidObject = SolidObject()”类型的初始化问题? 如果您没有空的 init() 块,则不能仅使用 SolidObject() 启动新实例,因为另一个 init 将是唯一可见的签名。如果你把上面的代码扔到一个操场上,如果你删除空的 init(),你可以看到 'var solidObject = SolidObject()' 的错误

以上是关于如何在可编码结构中使用计算属性(swift)的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4 可编码;如何使用单个根级密钥解码对象

多部分请求 - 带有 UIImage 的可编码结构

在 swift 4 中使用可编码的 JSON 时出错?

将可编码结构编码为 Alamofire POST 参数 - Swift

如何在 Swift 中将计算的闭包属性转换为闭包?

Swift:如何将可编码类型作为函数输入传递给编码或解码 json