typesX不从Yinheritance
下面的Swift代码在最后一行产生这个错误: Type 'E' does not inherit from 'C<Self>'
。 不知道这里发生了什么事。 任何线索将不胜感激。
class C<T> {} protocol P { typealias E : C<Self> } class A : P { typealias E = C<A> } class S<U : P> {} class C2<T> : S<A> {}
更新:我简化了破碎的例子。 在这个问题的编辑历史中可以find旧版本(milos的答案提到)。
我已经重新命名了你的标识符,所以我可以考虑一下:
protocol P { typealias E : C<Self> } class A : P { typealias E = C1<Any> } class B : P { typealias E = C2<Any> } class C<T> {} class C1<T> : C<A> {} class S<T, U : P> : C<T> {} // <-- mark! class C2<T> : S<B, A> {}
这应该最终,而且几乎是这样。 实际上,你想要的是:
class B : P { typealias E = C<B> // which is what P requires (same with class A) }
但是,在标记行中,在定义class S
您要求编译器检查U : P
的types,然后将B
作为具体types进行检查。 不幸的是,在这一点上, B
与P
的一致性仍然没有解决(也就是说,它本身是用C2 : S : C
,这就是你用U : P
去的地方)。 删除: P
在U : P
删除错误,虽然这可能不是你想要的。 然后,再次,取决于你想要什么,可能有任何数量的解决scheme:)
编辑
以下是对@ igul222的简单代码示例的回应。 但是,我仍然认为,编译器只是返回一个不太有用的错误消息,这实际上是由recursiontypes定义引起的。 例如,考虑一下如果你自己定义一个enum
:
enum E { case C(E) // error: recursive value type 'E' is not allowed }
现在,这可能也是以下问题:
class C<T> {} protocol P { typealias E : C<Self> var c: E { get } } final class A : P { typealias E = C<A> var c: E { return E() } } // --> error: type 'A' does not conform to protocol 'P' // --> note: protocol requires property 'c' with type 'E' // --> note: candidate has non-matching type 'E'
…这项工作(你的要点的一个版本):
class C<T> {} protocol P { typealias E : C<Self> } final class A : P { typealias E = C<A> } class X<U : P> {} X<A>() // --> error: type 'E' does not inherit from 'C<`Self`>'
… 或这个:
class C<T> {} protocol P { typealias E : C<Self> } final class A : P { typealias E = C<A> } let a = A() func f<T: P>(T) {} f(a) // --> error: 'A' is not identical to '`Self`'
编译器似乎在说的是, C<Self>
中的C<Self>
还不是A
,也就是说A
还不是A
Self
因为它必须符合P
,而P
又要等待C<Self>
检出。 。但是下面的工作,因为A
本身不再定义一个关联的types:
class C<T> {} protocol P { var c: C<Self> { get } } final class A : P { typealias E = C<A> // just a typealias, no longer an associated type var c: E { return E() } }
一些函数式编程模式需要recursion定义的types,所以在Swift中可能会很好。 然而,目前我不能确定,即使编译器允许它的定义,也可以有效地遵循一个与T<Self>
forms的关联types的协议。否则,这些都应该在运行时才起作用。
编辑2
我刚刚升级到Xcode 6.1 GM种子 ,事情已经改变! 下面的代码片段,以前不会编译,现在编译并显示运行正常!
protocol A { var b: B? { get set } } protocol B { var a: A? { get set } } class Ca: A { var b: B? } class Cb: B { var a: A? } let a = Ca() // --> {nil} let b = Cb() // --> {nil} ab = b // --> {{{...}}} ba = a // --> {{{...}}}
但是,这种改进不会扩展到recursion定义的关联types。