-1

从 Swift 中的枚举开始:

enum UnitCode:UInt {
    case Unknown = 0
    case Hz = 1
    case GPM = 2
    case M3_Hour = 3
    case mA = 4
    case PSI = 5
    case Bar = 6
}

对于大多数人来说,这样的表达方式:

let text = "\(aUnitCode)"

将产生一个很好的结果,因为打印的形式与代码形式相匹配(例如 .Hz == "Hz")。

但是对于M3_Hour,我想将其打印为m³/hr. 所以符合CustomStringConvertable,对吧?我认为以下方法行不通:

extension UnitCode: CustomStringConvertible {
    var description:String {
        return self == .M3_Hour ? "m³/hr" : String(describing: self)
    }
}

它没。无限递归。认为这样。但是 Swift 经常让我感到惊讶(无论是好的还是坏的)。

如果枚举是超级/子类型关系,我会调用描述的“超级”版本来获取枚举的“默认”文本呈现。但我不确定如何在我的错误分支中获得“枚举的默认字符串化”,以便我可以将它调整为一个不同的值。有没有办法做到这一点?

4

3 回答 3

2

我认为您的实际代码的问题在于您String(describing:)在 CustomStringConvertible 实现中的使用。如果我们忽略 CustomStringConvertible 而只写一个自定义属性,你可以做这样的事情:

enum UnitCode: UInt {
    case Unknown = 0
    case Hz = 1
    case GPM = 2
    case M3_Hour = 3
    case mA = 4
    case PSI = 5
    case Bar = 6
    var toString : String {
        return self == .M3_Hour ? "m³/hr" : "\(self)"
    }
}

我没有看到任何递归。(但我应该补充一点,我认为这很脆弱;我们依赖的功能在未来可能无法使用。Apple 可以随时更改对象的描述。)

真正的答案是,要么您应该使用 String 原始值而不是 Int 原始值,否则您应该提供所有案例的完整switch信息,将每个案例与可用字符串相关联。

于 2021-06-02T23:06:15.343 回答
1

对风格和变通方法的评论表示赞赏。我正在寻找的答案来自 Swift 论坛,并且很简单:

不幸的是,你不能。您需要调用的函数是标准库的内部函数。

因此,基本上,当您不提供自己的description实现时,无法使用从枚举到其编码字符串的回退转换的机制。

(@matt 在评论中也说过,如果他回答了这个问题,我会为他的巨大声誉加分)

于 2021-06-03T18:29:55.670 回答
0

这对我有用,希望这是你所期望的。

enum UnitCode: UInt {
    case Unknown = 0
    case Hz = 1
    case GPM = 2
    case M3_Hour = 3
    case mA = 4
    case PSI = 5
    case Bar = 6
}

let anUnit: UnitCode = .M3_Hour

extension UnitCode: CustomStringConvertible {
    var description: String {
        switch self {
        case .M3_Hour:
            return "m³/hr"
        default:
            return String(describing: self)
        }
    }
}

print(anUnit.self)
//m³/hr
于 2021-06-02T22:21:42.107 回答