首页 > 解决方案 > 如何在符合协议的非 RawRepresentable 枚举上实现 CustomStringConvertible?

问题描述

考虑以下代码,其中包括:

import Foundation

protocol P { }

enum E0: P { case a }

enum E1: P { case b }

func f(p: P) {
    print("\(type(of: p)).\(p)")
}

let e0_a = E0.a
let e1_b = E1.b

f(p: e0_a)  // prints "E0.a"
f(p: e1_b)  // prints "E1.b"

我希望能够打印一个描述p形式参数的字符串:

Name of type implementing Pcase of P

如函数所示f(),这工作得很好,我得到了我想要的输出。

如果可能的话,我想做的是实现一个生成相同字符串的CustomStringConvertible扩展。P

这可能吗?

这是一种行不通的方法:

protocol P: CustomStringConvertible { }

extension P {
    var description: String { return "\(type(of: self).\(self)" }
}

这不起作用,因为\(self)导致description递归调用自身直到堆栈溢出。

这是另一种不起作用的方法:

protocol P: CustomStringConvertible { }

extension P where Self: RawRepresentable {
    var description: String { return "\(type(of: self)).\(self.rawValue)" }
}

这种方法不起作用,因为E0is not RawRepresentable。引擎盖下有一些魔法,即使枚举没有,Swift 也可以打印枚举的案例名称rawValue,但我不知道如何访问它。使用类似Mirror(reflecting: p).description打印 p 的类型,而不是枚举的案例名称。

谢谢你的任何想法。正如我所说,它可以在接收 a 的函数中完成P,但 aCustomStringConvertible会更干净。

标签: swiftenumsprotocols

解决方案


推荐阅读