我的代码中有一些协议层次结构,我有定义我使用的对象的协议和定义与这些对象一起使用的函数的协议 .
对象协议由其他对象协议继承,这些协议为原始协议添加了更多功能,使用它们的功能也是如此 . 问题是我找不到专门化函数的方法来只接受继承的参数 .
这里有一些代码来澄清我正在尝试做的事情:
protocol A {
var foo: String { get set }
}
protocol B: A {
var bar: String { get set }
}
struct Test: B {
var foo: String = "foo"
var bar: String = "bar"
}
protocol UseAProtocol {
static func use<T: A>(_ obj: T)
}
protocol UseBProtocol: UseAProtocol {
}
extension UseBProtocol {
//If I change the requirement to <T: B> this won't conform to `UseAProtocol`.
static func use<T: A>(_ obj: T) {
print(obj.foo)
// print(obj.bar) - Since obj does not conform to `B` I can't access ".bar" here without a forced casting.
}
}
struct Manager: UseBProtocol {
}
Manager.use(Test())
我想要做的是使 UseBProtocol
上的 use
函数只接受符合 B
的对象 . B
继承自 A
,但当我从 <T:A>
更改为 <T:B>
时,我收到一条错误消息,指出Manager不符合 UseAProtocol
,我必须将其更改回 <T:A>
.
我知道我可以使用继承协议上的 associatedtype
和 where
子句来实现这一点 - 这就是我今天使用的 - 但是我想将通用要求移到方法中,这样我就可以将它们全部组合在同一个结构中(我有很多这个层次结构和使用 associatedtype
我必须按层次结构使用一个结构 . 当有条件的一致性来到Swift时,这可能是 associatedtype
,但直到他们......
我也可以使用 as!
在 UseBProtocol
实现上强制从 A
到 B
的转换,但这是一个非常糟糕的解决方案,错误只会在运行时抛出 .
有没有办法实现我正在寻找的东西?
1 回答
看起来你正在寻找的是
UseAProtocol
中的associatedType
而不是使use
函数通用 .通过在
UseAProtocol
中声明关联类型并将use
的函数签名更改为static func use(_ obj: ProtocolType)
,您的代码编译得很好,您可以从Manager
访问foo
和bar
.