如何将Swift对象输出为可复用Swift代码至调试器?
实现Swift对象到可重构代码字符串的转换函数
要实现将运行时对象转为可直接复制使用的Swift代码,核心是利用Swift的Mirror反射API获取对象的类型与属性信息,递归处理每个属性值生成对应代码。以下是完整实现:
核心实现代码
import Foundation func swiftCode<T>(from object: T) -> String { let mirror = Mirror(reflecting: object) // 处理枚举、结构体、类类型 if let displayStyle = mirror.displayStyle { switch displayStyle { case .enum: return "\(mirror.subjectType).\(object)" case .struct, .class: let properties = mirror.children.compactMap { child -> (String, String)? in guard let label = child.label else { return nil } let valueCode = swiftCode(from: child.value) return (label, valueCode) } let propertyStrings = properties.map { "\($0): \($1)" }.joined(separator: ", ") return "\(mirror.subjectType)(\(propertyStrings))" default: break } } // 处理可选值 if let optionalMirror = Mirror(reflecting: object).superclassMirror, optionalMirror.displayStyle == .optional { if let someValue = optionalMirror.children.first?.value { return "\(swiftCode(from: someValue))?" } else { return "nil" } } // 处理数组与字典 if let array = object as? [Any] { let elements = array.map { swiftCode(from: $0) }.joined(separator: ", ") return "[\(elements)]" } if let dictionary = object as? [AnyHashable: Any] { let entries = dictionary.map { "\(swiftCode(from: $0.key)): \(swiftCode(from: $0.value))" }.joined(separator: ", ") return "[\(entries)]" } // 处理基础数据类型 switch object { case let string as String: return "\"\(string.replacingOccurrences(of: "\"", with: "\\\""))\"" case let number as Int, let number as Double, let number as Float, let number as Bool: return "\(number)" default: return "\(object)" } } // 封装打印函数 func printCode<T>(t: T) { debugPrint(swiftCode(from: t)) }
使用示例
测试你提供的Foo结构体:
struct Foo { var bar: String } let testFoo = Foo(bar: "WooHoo!") printCode(t: testFoo)
控制台输出:"Foo(bar: \"WooHoo!\")"
再测试包含嵌套类型、可选值和集合的复杂对象:
struct Bar { var count: Int? var items: [String] } let testBar = Bar(count: 5, items: ["a", "b"]) printCode(t: testBar)
输出:"Bar(count: 5?, items: [\"a\", \"b\"])"
注意事项
- 初始化器要求:结构体默认支持成员初始化器;类需要确保存在可访问的成员初始化器,若要支持自定义初始化器,需扩展逻辑识别特定初始化器参数。
- 私有属性限制:
Mirror无法获取私有属性信息,这类属性不会出现在生成的代码中。 - 复杂类型兼容:闭包、
UnsafePointer等无法序列化的类型,会直接输出默认描述字符串,无法直接复用。 - 自定义扩展:如果需要支持特定自定义类型的特殊代码生成,可以在
swiftCode函数中添加对应类型的判断分支。
内容的提问来源于stack exchange,提问作者Scott Wood
相关产品推荐
相关产品推荐

