我希望 Swift 能够让我为具有指定条件的类型创建扩展where
堵塞。我想象我可以根据具体的泛型类型值使用不同的扩展来扩展相同的泛型类型(T
)。但不是。以下示例演示了我的问题:
protocol P {
associatedtype Prop
var property: Prop { get }
}
enum E<T: P> {
case single(T)
case double(T)
}
extension E: P where T.Prop == Int {
var property: Int {
switch self {
case .single(let o): return o.property
case .double(let o): return o.property * 2
}
}
}
extension E: P where T.Prop == String {
var property: String {
switch self {
case .single(let o): return o.property
case .double(let o): return o.property + o.property
}
}
}
struct Int4: P {
var property: Int {
return 4
}
}
struct StringHello: P {
var property: String {
return "Hello"
}
}
print(E.single(Int4()).property)
print(E.double(StringHello()).property)
下面的错误和注释是编译的结果。
错误:“E”与协议“P”的一致性冲突;即使有不同的条件界限,也不能有多个一致性extension E: P where T.Prop == String {
注意:“E”在此声明符合协议“P”extension E: P where T.Prop == Int {
难道真的不可能吗?为什么?我可以用我的代码做什么才能成功?
一些细节来证明我的真实情况中的问题。
我有一些通用枚举,它与许多不同的包装类型一起使用。
enum Color<T> {
case red(T), green(T)
func map<T2>(_ transform: (T) -> T2) -> Color<T2> {
switch self {
case .red(let o): return .red(transform(o))
case .green(let o): return .green(transform(o))
}
}
}
很多时候,我需要对 Color 进行不同的扩展,以使其符合不同的协议,具体取决于包装的类型。有时这些协议具有相同的基础(超级)协议,因此,我遇到了当前的问题。有时我无法扩展 Color 以使所有派生协议都符合此基本(超级)协议,因为我需要不同的实现。
难道不可能吗?是和不是。目前在 Swift 中还不可能实现,因为它已经实现了。原则上是可以实施的。
其名称为“重叠一致性”,并且被明确且有意地拒绝。您可以在“考虑的替代方案”部分找到基本原理SE-0143 有条件的一致性。 TL;DR 是:因为它真的很复杂。
如果不了解您到底想用它做什么,我们无法提供太多指导。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)