我的代码中有一些协议层次结构,我有定义我使用的对象的协议和定义与这些对象一起使用的函数的协议.
对象协议由其他对象协议继承,这些协议为原始协议添加了更多功能,使用它们的功能也是如此.问题是我找不到专门化函数的方法来只接受继承的参数.
这里有一些代码来澄清我正在尝试做的事情:
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())
Run Code Online (Sandbox Code Playgroud)
我想要做的是使use函数在UseBProtocol唯一符合的接受对象上B.B继承自A,但当我改变时<T:A>,<T:B>我得到一个错误,说经理不符合UseAProtocol,我必须改回来<T:A>.
我知道我可以使用associatedtype和where继承协议的条款 - 这就是我今天使用的 - 但是我想将通用要求移到方法中,这样我就可以将所有这些组合在同一个结构下(我有很多这个层次结构和使用associatedtype我必须按层次结构使用一个结构.当有条件的一致性来到Swift时,这是可能的associatedtype,但直到他们......
我还可以使用as!强制从其铸造A到B上UseBProtocol实现,但这是一个非常糟糕的解决方案,错误只会在运行时抛出.
有没有办法实现我正在寻找的东西?
看来您实际上正在寻找的是 inassociatedType而UseAProtocol不是使use函数通用。
通过在 中声明关联类型UseAProtocol并更改 的函数签名,您use的static func use(_ obj: ProtocolType)代码可以正常编译,并且您可以从访问foo和。barManager
protocol AProtocol {
var foo: String { get set }
}
protocol BProtocol: AProtocol {
var bar: String { get set }
}
struct Test: BProtocol {
var foo: String = "foo"
var bar: String = "bar"
}
protocol UseAProtocol {
associatedtype ProtocolType
static func use(_ obj: ProtocolType)
}
protocol UseBProtocol: UseAProtocol {
}
extension UseBProtocol {
static func use(_ obj: BProtocol) {
print(obj.foo)
print(obj.bar)
}
}
struct Manager: UseBProtocol {
}
Manager.use(Test()) //prints both "foo" and "bar"
Run Code Online (Sandbox Code Playgroud)