有没有办法在 Swift 中使用制表符来均匀间隔描述字符串



覆盖自定义类的描述变量:

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

最新更新