Generics 怎么说;“同一类”;迅速地
如果Swift泛型类型约束是协议名称,我可以要求约束到该协议的两个类型是相同的类型。例如:Generics 怎么说;“同一类”;迅速地,generics,swift,Generics,Swift,如果Swift泛型类型约束是协议名称,我可以要求约束到该协议的两个类型是相同的类型。例如: protocol Flier {} struct Bird : Flier {} struct Insect: Flier {} func flockTwoTogether<T:Flier>(f1:T, f2:T) {} 问题是,我可以使用WellBehavedDog和NoisedDog一起调用Walktwow。这就是我想要阻止的 这里有两个问题: 有没有一种方法可以说不能用WellBeh
protocol Flier {}
struct Bird : Flier {}
struct Insect: Flier {}
func flockTwoTogether<T:Flier>(f1:T, f2:T) {}
问题是,我可以使用WellBehavedDog和NoisedDog一起调用Walktwow
。这就是我想要阻止的
这里有两个问题:
- 有没有一种方法可以说不能用WellBehavedDog和NoisedDog调用
一起行走
- 这是虫子吗?我这样问是因为如果我不能用泛型来表达这一点,很难理解为什么泛型约束作为类名是有用的,因为我们可以用普通函数得到相同的结果
- 从本质上说,这不是一个答案,但可能还有更多的数据。。。问题是当你打电话时:
walkTwoTogether(NoisyDog(), WellBehavedDog())
Swift可以把这两个实例都当作Dog
(又称为upcast)的实例来处理——我们需要它,这样我们就可以用A
的子类调用类A
的方法。(我知道你知道这一点。)
Swift不向上转换协议,因此唯一的方法是为超类不符合的子类指定协议:
protocol Walkable {}
extension NoisyDog : Walkable {}
extension WellBehavedDog: Walkable {}
func walkTwoTogether<T: Dog where T: Walkable>(d1:T, d2:T) { }
walkTwoTogether(NoisyDog(), WellBehavedDog())
// error: type 'Dog' does not conform to protocol 'Walkable'
protocolwalkable{}
扩展名noisedog:Walkable{}
扩展井行波道:可行走{}
func walktowethowe(d1:T,d2:T){}
一起演练(noisedog(),welleHavedDog())
//错误:类型“Dog”不符合协议“Walkable”
错误消息明确显示发生了什么-调用此版本的
walkToTogether
的唯一方法是将子类实例上溯到Dog
,但是Dog
不符合Walkable
我认为这应该被视为一个bug,因为inout
参数改变了类型要求:
func walkTwoTogether<T:Dog>(inout d1:T, d2:T) {
func一起演练(inout d1:T,d2:T){
现在,它具有预期的行为,您只能传递相同类型的两个值。(在Swift 1.2和Swift 2 beta 5中测试)对我来说,这似乎是预期的行为?您已将可选项约束为Dog类型。您的两个子类都符合该类型,并且声明中没有任何内容约束它们。如果有办法实现您的要求,我希望它需要一个
where
子句,如
,但这也会引发一个错误。@cmyr Yes,当然,我试过了。这就是为什么我问我所做的不是如何做,是否有可能做到。:)如果Dog
是一个协议,这一切都会起作用。非协议类型不能强制执行通用约束。(某种类型擦除)@马特这就是为什么我很好奇为什么T:SomeClass是允许的。文档明确地说你可以这样做,但我不明白为什么它有用。我的意思是,如果它不强制执行任何东西,那是为什么?如果我想让任何两个狗类子类可以一起行走,我可以使用一个非泛型函数。看起来你在自言自语,马特(T).:)幸运的是,我没有像我最初向自己提出的那样提出这个问题,这是为了区分Dog和noisedog!不允许使用子类!是和否。这是合法的:var d:Dog=wellehaveddog();walktoweach(&d,noisedog())
在任何情况下,如果有缺陷,我想我们最多只能说是不一致;不清楚哪一个是对的。@matt Your是对的,可能是其中一个。在您的情况下,您必须用inout
标记两个参数。有趣的是,如果不使用泛型约束,它的行为几乎相同。我比e更困惑没错!但是你的数据真的很有趣,这是毫无疑问的。
func walkTwoTogether<T:Dog>(inout d1:T, d2:T) {