【发布时间】:2022-01-23 03:12:00
【问题描述】:
我使用enum(s) 定义所有自定义错误,例如:
public enum MyErrorEnum: String, LocalizedError {
case FileNotFound = "Failed to find file."
public var errorDescription: String? { rawValue }
}
但有些错误需要额外的context,例如在消息中添加文件路径。
不幸的是,由于 Swift 枚举不支持实例变量,我尝试了一些变通方法,例如:
private var KEY_CONTEXT: UInt8 = 0;
public enum MyErrorEnum: String, LocalizedError {
case FileNotFound = "Failed to find file."
public var errorDescription: String? { rawValue }
public var context: String {
return objc_getAssociatedObject(self as NSObject, &KEY_CONTEXT)
as? String ?? "";
}
@discardableResult
public mutating func withContext(_ value: String) -> Self {
objc_setAssociatedObject(
self as NSObject, &KEY_CONTEXT, value as NSString,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return self;
}
}
请注意,上述内容不会在 Xcode 12 中引发任何编译和/或运行时错误,但只是不起作用。
后来,我收到通知 Xcode 13 引发以下编译错误: "
Cannot convert value of type 'MyErrorEnum' to type 'NSObject' in coercion"
我也已经尝试过简单地将String 更改为实现ExpressibleByStringLiteral 的自定义StringWithContext 类,但即使这样也不起作用(可能是因为枚举的rawValue 以某种方式受到更改保护)。
有什么方法可以为所述枚举添加额外的变量?
【问题讨论】:
-
现在有了比您之前的问题更多的上下文,看起来枚举根本不适合这个用例。使用具有两个属性的结构 -
context和errorType,其中errorType是一个简单的枚举。但是,如果每种情况都与不同类型的上下文相关联,请考虑使用associated values。 -
@Sweeper 问题是干净的投掷和接球,无需重新投掷和复制/粘贴。 首先, 我想要没有复制/粘贴的消息(
enum非常独特,没有复制/粘贴),但不知何故需要有可变的上下文/详细信息。 其次, 我希望能够分别catch每个case,而不是捕获整个struct然后在catch中执行switch,并且希望避免忘记重新抛出我们的案例不要处理。