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进行检查。 不幸的是,在这一点上, BP的一致性仍然没有解决(也就是说,它本身是用C2 : S : C ,这就是你用U : P去的地方)。 删除: PU : 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。