注意下面的编译:
protocol Foo {
associatedtype A
}
struct Container<F: Foo> {
func f(a: F.A) { }
}
然而,在的情况下:
struct Container<F: Foo> {
func f<A : F.A>(a: A) { } // error: inheritance from non-protocol, non-class type
}
...类型F.A
完全不受约束,因此它很可能是,比如说,一个Int
,你不能从:
语法继承或符合。
如果你真的需要比(a: F.A)
一个更通用的解决方案,然后沿着这些路线的东西可能会做到这一点:
protocol Bar { }
protocol Foo {
associatedtype A : Bar
}
struct Container<F: Foo> {
func f<A : Bar>(a: A) { }
}
现在,您可以表达对使用Bar
协议a
参数的任何预期。
更妙的是,你可能能够实现方法的Foo
扩展:
protocol Foo {
associatedtype A
func f(_: A) // if you want this to be a requirement
}
extension Foo /* where A is constrained so you can do something with it */ {
func f(a: A) { }
}
在我的使用情况下,'Container'方法'F'必须被约束的Foo'子类类型。也就是说,它必须是“Foo.A”类型或子类。当你说F.A没有约束是问题时,我不确定你是对的。毕竟,如果我们使'associatedtype A:Bar','func f (a:A){}'仍然失败。 – Stephen
我从来没有建议'associatedtype A:Bar','func f (a:A){}' - 这肯定会失败。请仔细看一下'Bar'代码片段......还要注意,如果这是您需要的,您可以用一个特定的类来替换'Bar'。至于“不确定”,你有没有对我的解释有任何特别的反对意见(例如'F.A'是'Int'的情况下)? – milos
我注意到了我们的片段之间的区别。我在回应你引用'F.A型完全无约束'的地方作为错误的原因。即使有限制,结果也是一样的。为什么不能将关联的类型用作约束? – Stephen