我的代码中有一些协议(protocol)层次结构,其中我有定义我使用的对象的协议(protocol)和定义用于此对象的函数的协议(protocol)。
对象协议(protocol)由其他对象协议(protocol)继承,这些协议(protocol)为原始协议(protocol)添加了更多功能,使用它们的功能也是如此。问题是我找不到专门化函数以仅采用继承参数的方法。
这里有一些代码来阐明我正在尝试做的事情:
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())
我想做的是制作 use
UseBProtocol
上的函数只接受符合 B
的对象. B
继承自 A
,但是当我从 <T:A>
更改时至 <T:B>
我收到一条错误消息,指出 Manager 不符合 UseAProtocol
我必须把它改回 <T:A>
.
我知道我可以使用 associatedtype
来做到这一点和 where
继承协议(protocol)上的子句——这就是我今天使用的——但我想将通用要求移动到方法中,这样我就可以将它们全部分组在同一个结构下(我有很多这样的层次结构,通过使用 associatedtype
我必须按层次结构使用一个结构)。当条件一致性出现在 Swift 中时,associatedtype
是可能的。 , 但直到他们...
我也可以使用 as!
从A
强制类型转换至 B
在 UseBProtocol
上实现,但这是一个非常糟糕的解决方案,错误只会在运行时抛出。
有什么方法可以达到我的要求吗?
最佳答案
看起来您实际上正在寻找的是 UseAProtocol
中的 associatedType
而不是使 use
函数通用。
通过在 UseAProtocol
中声明关联类型并将 use
的函数签名更改为 static func use(_ obj: ProtocolType)
您的代码编译正常,您可以从 Manager
访问 foo
和 bar
。
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"
关于swift - 专门化协议(protocol)继承的通用功能要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48381500/