假设我有一个像这样的对象:
class MyClass
{
let a_number : Int?
let a_string : String?
let an_array_of_strings : Array<String>?
let an_array_of_objs : Array<Any>?
}
我怎么能这样做,以便当我将这个对象打印到控制台时,z是这样缩进的:
MyClass
a_number = 4
a_string = "hello"
an_array_of_strings = ["str1",
"str2",
"str3"]
an_array_of_objs = [MyClass
a_number = 5
a_string = "world"
an_array_of_strings = nil
an_array_of_objs = nil]
答案 0 :(得分:1)
我使用递归函数和缩进的累加器参数来做到这一点。它默认为没有缩进,并且在每次递归调用时增加第一列的宽度:
customObj.arrInt & customObj.objectSOC
此功能使用my answer to another question
中的func describe<T>(_ x: T, indent: String = "") -> String
{
let mirror = Mirror(reflecting: x)
guard !mirror.children.isEmpty else { return x is String ? "\"\(x)\"" : "\(x)" }
switch mirror.displayStyle! {
case .tuple:
let descriptions = mirror.children.map { describe(unwrap($0.value), indent: indent) }
return "(" + descriptions.joined(separator: ",\n\(indent)") + ")"
case .collection:
let descriptions = mirror.children.map { describe(unwrap($0.value), indent: indent) }
return "[" + descriptions.joined(separator: ",\n\(indent)") + "]"
case .dictionary:
let descriptions = mirror.children.map { (child: Mirror.Child) -> String in
let entryMirrors = Array(Mirror(reflecting: unwrap(child.value)).children)
return describe(unwrap(entryMirrors[0].value), indent: indent) + ": "
+ describe(unwrap(entryMirrors[1].value))
}
return "[" + descriptions.joined(separator: ",\n\(indent)") + "]"
case .set:
let descriptions = mirror.children.map { describe(unwrap($0.value), indent: indent) }
return "Set(" + descriptions.joined(separator: ",\n\(indent)") + ")"
default:
let childrenWithLabel = mirror.children.filter { $0.label != nil }
let separator = " = "
let firstColumnWidth = (childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0)
+ separator.characters.count
let subindent = indent + String(repeating: " ", count: firstColumnWidth)
let lines = childrenWithLabel.map {
indent
+ ($0.label! + separator).padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0)
+ describe(unwrap($0.value), indent: subindent)
}
return (["\(mirror.subjectType)"] + lines).joined(separator: "\n")
}
}
功能
unwrap(_:)
当像这样使用func unwrap<T>(_ any: T) -> Any
{
let mirror = Mirror(reflecting: any)
guard mirror.displayStyle == .optional, let first = mirror.children.first else {
return any
}
return first.value
}
时(我使describe(_:)
成为一个结构,所以我可以使用成员初始化器):
MyClass
然后输出
struct MyClass: CustomStringConvertible
{
let a_number : Int?
let a_string : String?
let an_array_of_strings : Array<String>?
let an_array_of_objs : Array<Any>?
var description: String { return describe(self) }
}
print(MyClass(a_number: 4, a_string: "hello",
an_array_of_strings: ["str1", "str2", "str3"],
an_array_of_objs: [
MyClass(a_number: 5, a_string: "world",
an_array_of_strings: nil, an_array_of_objs: nil)]))
请注意,这仅使用您的具体示例和一些简单的添加进行测试。我对MyClass
a_number = 4
a_string = "hello"
an_array_of_strings = ["str1",
"str2",
"str3"]
an_array_of_objs = [MyClass
a_number = 5
a_string = "world"
an_array_of_strings = nil
an_array_of_objs = nil]
的强制展开也不满意,但在我的浅层测试中,这只发生在mirror.displayStyle
为空时,前面的mirror.children
所涵盖。如果有人对此进行更密切的调查,我会喜欢评论。我在guard
的文档中找不到任何内容。
就像在my answer to your related question中一样,我混淆了Mirror
应该在哪里。恰恰相反,这个时候,呃! :)