我确实写了一些代码来将一些结构体以JSON格式保存到磁盘上。但是,如果我将其保存在一个变量中并保留该变量并使用它来解码它,那么UUID就不同了。
import Foundation
import PlaygroundSupport
import Swift
struct Project: Codable, Identifiable, Hashable {
let id: UUID = UUID()
let id2: String = UUID().uuidString
let name: String
}
let project = Project(name: "PP50")
let encodedData = try JSONEncoder().encode(project)
let jsonString = String(data: encodedData,
encoding: .utf8)
print(project.id)
print(project.id2)
print(project.name)
print(jsonString)
print("===================")
if let dataFromJsonString = jsonString?.data(using: .utf8) {
let projectFromData = try JSONDecoder().decode(Project.self, from: dataFromJsonString)
print(projectFromData)
print(projectFromData.name)
print(projectFromData.id) // <<< why is the id and id'2 different
print(projectFromData.id2)
}
结果是:
826FEC8A-7FE0-4E6C-8DC1-A0DFA4FC75BE
2D15A1B8-B936-4829-8DC2-9C44B261712E
PP50
Optional("{\"id\":\"826FEC8A-7FE0-4E6C-8DC1-A0DFA4FC75BE\",\"id2\":\"2D15A1B8-B936-4829-8DC2-9C44B261712E\",\"name\":\"PP50\"}")
===================
Project(id: E951D459-3C0E-43A3-B9C6-2CCF2EB1AEE3, id2: "3C97B5C3-054D-4372-800D-9210439F48C2", name: "PP50")
PP50
E951D459-3C0E-43A3-B9C6-2CCF2EB1AEE3
3C97B5C3-054D-4372-800D-9210439F48C2
也许一个简单的答案,但我还没有看到它。为什么id的结果与创建的结果不同?为什么?如何解决这个问题?
3条答案
按热度按时间uxhixvfz1#
正如其他人在评论和其他回答中所说的那样,使用初始值声明的
let
属性不会被解码,并且将使用默认值。在这种情况下,默认值是新的UUID。将属性更改为
var
将在解码时包含它们,即使使用默认值。然而,由于标识符可能不应该是可变的,因此将属性保持为let
但具有相同的外部可见API的实现是使用显式初始化器来提供默认值:通过在初始化器中提供默认值,
Project
仍然可以仅使用名称创建。由于属性本身没有初始化器,因此它们将被解码。epfja78i2#
您需要做的就是
var
声明您的id
属性,它们将包含在解码中。rqqzpn5f3#
在创建
Project
的示例时,id
和id2
是从UUID()
获取默认值的常量--在解码JSON时不能修改这些值。id
和id2
需要是变量(var
),而不是常量(let
)。通过这样做,可以通过JSON内容修改值。