【发布时间】:2021-03-05 11:45:02
【问题描述】:
我想开发一个递归 Either 类型作为 Swift 枚举(至少是部分工作版本 (;),因此一直在玩泛型(尝试使用类型系统)。
这是我目前所拥有的:
enum NumericEitherEnum<Left, Right> {
case left(Left)
case right(Right)
var left: Left? {
switch self {
case .left(let leftie) where leftie is NumericEitherEnum<Int, Float>:
return (leftie as? NumericEitherEnum<Int, Float>)?.left // This won't work (obviously)
case .left(let left):
return left
case .right(_):
return nil
}
}
var right: Right? {
switch self {
case .left(_):
return nil
case .right(let right) where right is NumericEitherEnum:
return (right as? NumericEitherEnum)?.right // This assumes the generic parameters of Left, Right in the current enum so won't work.
case .right(let right):
return right
}
}
}
我在 Xcode 中收到神秘的诊断错误消息,我无法解决:
- '用
NumericEitherEnum<Int, Float>替换(leftie as? NumericEitherEnum<Int, Float>)?' - 'Enum case 'left' 不能用作实例成员'
我想要达到的目标:
print(NumericEitherEnum<NumericEitherEnum<Int, Float>, NumericEitherEnum<Int, Float>>.left(.left(3)).left ?? "failed :(") // Parses the innermost value 3
修复 - 它不会修复错误或建议如何实际解决根本原因。我认为这可能是编译器解析的边缘情况(甚至可能是错误);)。我也意识到实际上返回 Int 为 Left? 类型在逻辑上没有意义,但有什么方法可以在类型系统中表达这一点(我尝试了关联类型,但我仍然不知道如何使这个动态)。处理具有不同泛型类型签名的嵌套枚举也存在问题(不知道如何表达)。
如何以更好的方式解决此问题?理想情况下,我希望有一个干净的调用站点,没有太多间接和额外的数据结构,但如果这实际上无法实现,我愿意尝试不同的数据结构。
【问题讨论】: