Swift 中的 Codable 是什么?如何使用 Codable 进行编码和解码?CustomStringConvertible 和 CustomDebugStringConvertible 有什么区别?
Swift 中的 Codable 是一个类型别名,结合了 Encodable 和 Decodable 协议,用于在数据类型和外部表示(如 JSON、Property List)之间进行转换。
Codable 的基本用法:
swiftstruct User: Codable { let id: Int let name: String let email: String } // 编码 let user = User(id: 1, name: "John Doe", email: "john@example.com") let encoder = JSONEncoder() if let jsonData = try? encoder.encode(user) { print(String(data: jsonData, encoding: .utf8)!) } // 解码 let decoder = JSONDecoder() if let decodedUser = try? decoder.decode(User.self, from: jsonData) { print(decodedUser.name) }
自定义编码键:
swiftstruct User: Codable { let id: Int let name: String let email: String enum CodingKeys: String, CodingKey { case id case name = "full_name" case email = "email_address" } }
自定义编码和解码:
swiftstruct DateWrapper: Codable { let date: Date enum CodingKeys: String, CodingKey { case timestamp } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let timestamp = try container.decode(Double.self, forKey: .timestamp) self.date = Date(timeIntervalSince1970: timestamp) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(date.timeIntervalSince1970, forKey: .timestamp) } }
Codable 的注意事项:
- 所有属性必须都是 Codable 类型
- 可选类型自动支持 Codable
- 数组和字典如果元素是 Codable 类型,也自动支持 Codable
- 可以使用 CodingKeys 自定义键名
CustomStringConvertible:
- 用于提供自定义的字符串表示
- 实现
description属性 - 用于
print()和String(describing:) - 示例:
swift
struct Point: CustomStringConvertible { let x: Int let y: Int var description: String { return "(\(x), \(y))" } } let point = Point(x: 3, y: 4) print(point) // (3, 4)
CustomDebugStringConvertible:
- 用于提供调试时的字符串表示
- 实现
debugDescription属性 - 用于调试器中的描述
- 优先级高于 CustomStringConvertible
- 示例:
swift
struct User: CustomDebugStringConvertible { let id: Int let name: String let password: String var debugDescription: String { return "User(id: \(id), name: \(name))" } } let user = User(id: 1, name: "John", password: "secret") debugPrint(user) // User(id: 1, name: John)
CustomStringConvertible 和 CustomDebugStringConvertible 的区别:
-
用途不同:
- CustomStringConvertible:用于常规字符串表示
- CustomDebugStringConvertible:用于调试字符串表示
-
实现方法不同:
- CustomStringConvertible:实现
description属性 - CustomDebugStringConvertible:实现
debugDescription属性
- CustomStringConvertible:实现
-
调用场景不同:
- CustomStringConvertible:
print()、String(describing:) - CustomDebugStringConvertible:
debugPrint()、调试器
- CustomStringConvertible:
-
优先级不同:
- 同时实现时,CustomDebugStringConvertible 优先级更高
- 调试时使用 debugDescription
- 常规时使用 description
最佳实践:
- 为数据模型实现 Codable
- 使用 CodingKeys 处理键名不匹配
- 为自定义类型实现 CustomStringConvertible
- 为调试实现 CustomDebugStringConvertible
- 在 debugDescription 中隐藏敏感信息