覆盖自定义类的描述变量:
override var description : String {
let mirrored_object = Mirror(reflecting: self)
let str:NSMutableString = NSMutableString()
for (index, attr) in mirrored_object.children.enumerated() {
if let property_name = attr.label as String! {
//str.append(" Attr (index): (property_name) = (attr.value)n")
str.append("t(property_name) = tt(attr.value)n")
}
}
return str as String
}
生成如下所示的输出:
userID = Optional(0)
username = Optional("testuser")
email = Optional("test@gmail.com")
有没有办法在输出中设置选项卡,以便属性值像这样很好地排列?
userID = Optional(0)
username = Optional("testuser")
email = Optional("test@gmail.com")
另外,有没有办法摆脱或缩短"可选"部分并仅显示值?
我不会使用选项卡,而是使用padding(...)
:
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let maxLen = childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0
let lines = childrenWithLabel.map { $0.label!.padding(toLength: maxLen, withPad: " ", startingAt: 0) + " = ($0.value)" }
return lines.joined(separator: "n")
}
对于像这样的结构
struct Foo: CustomStringConvertible
{
let userID = 42
let username = "Foo"
let verylongpropertyname: String? = "Bar"
}
这会产生
userID = 42
username = Foo
verylongpropertyname = Optional("Bar")
至于"可选"部分,它并不像 totiG 建议的那么容易,因为您从镜像中获得的值是 Any
型 .看到这个问题。
更新
我忽略了你想要一个稍微不同的格式。
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let separator = " = "
let firstColumnWidth = (childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0) + separator.characters.count
let lines = childrenWithLabel.map {
($0.label! + separator).padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0) + "($0.value)"
}
}
生产
userID = 42
username = Foo
verylongpropertyname = Optional("Bar")
更新 2
要摆脱"可选"的东西,请在此处查看我的答案。
如果您像这样使用(来自上述答案(unwrap()
或unwrapUsingProtocol()
description
:
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let separator = " = "
let firstColumnWidth = (childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0) + separator.characters.count
let lines = childrenWithLabel.map {
($0.label! + separator).padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0) + "(unwrap($0.value))"
}
return lines.joined(separator: "n")
}
这将产生
userID = 42
username = Foo
verylongpropertyname = Bar
尝试使用此方法。它首先计算属性的最大长度,然后使用它来填充属性名称:
let maxPropertyLength: Int = mirrored_object.children.map { Int($0.label?.characters.count ?? 0) }.max() ?? 0
for attr in mirrored_object.children {
if let propertyName = attr.label {
str.append("(propertyName.padding(toLength: maxPropertyLength + 2, withPad: " ", startingAt: 0)) = (attr.value)n")
}
}
return str as String