简体   繁体   English

类型X不继承自Y

[英]Type X does not inherit from Y

The following Swift code yields this error on the last line: Type 'E' does not inherit from 'C<Self>' . 以下Swift代码在最后一行产生此错误: Type 'E' does not inherit from 'C<Self>' Not sure what's going on here. 不知道这是怎么回事。 Any clues would be appreciated. 任何线索将不胜感激。

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> {}

Update: I simplified the broken example. 更新:我简化了破碎的例子。 The old version (to which milos' answer refers) can be found in this question's edit history. 可以在此问题的编辑历史记录中找到旧版本(milos的答案所指的版本)。

I have renamed your identifiers so I can think about them: 我已重命名了您的标识符,因此我可以考虑一下:

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> {}

This should eventually, and very nearly does, work out. 这应该最终并且几乎可以解决。 In effect, what you want is: 实际上,您想要的是:

class B : P {
    typealias E = C<B> // which is what P requires (same with class A)
}

However, on the marked line, where you are defining class S you are asking the compiler to check the type of U : P and then pass B as the concrete type to check. 但是,在标出的行上,您在定义class S是在要求编译器检查U : P的类型,然后将B作为要检查的具体类型。 Unfortunately, at this point B 's conformance to P is still unresolved (ie it is itself defined in terms of C2 : S : C , which is where you are going with U : P ). 不幸的是,在这一点上, BP的一致性仍未解决(即,它本身是根据C2 : S : C ,这就是您要使用U : P )。 Removing : P in U : P removes the error, though this may not be what you want. 删除: PU : P删除错误,虽然这可能不是你想要的。 Then again, depending on what you want, there may be any number of solutions :) 再根据您想要的内容,可能有许多解决方案:)

EDIT 编辑

The following is in response to @igul222's much simplified code example. 以下是对@ igul222简化的代码示例的响应。 I still, think, however, that the compiler is simply returning a less then helpful error message, which is really caused by the recursive type definition. 但是,我仍然认为,编译器仅返回的是一条不太有用的错误消息,这实际上是由递归类型定义引起的。 Consider, for example, if you define an enum in terms of itself: 考虑一下,例如,如果您根据自身定义enum

enum E {
    case C(E) // error: recursive value type 'E' is not allowed
}

Now, this is probably also the problem with the following: 现在,这可能也是以下问题:

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'

... neither does this work (a version of your gist): ...也不起作用(您的要点版本):

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`>'

... or this: ... 或这个:

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`'

What the compiler seems to be saying is that Self in C<Self> is not yet A , ie that A is not yet it Self since to be A it must conform to P which is in turn pending C<Self> checking out... But the following works because A no longer defines an associated type in terms of itself: 什么编译器似乎说的是SelfC<Self>还没有A ,即A尚未它Self ,因为是A它必须符合P这又挂起C<Self>检查出..但是,下面的方法是有效的,因为A不再根据自身定义关联的类型:

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() }
}

Some patterns of functional programming require recursively defined types, so it might be nice to have that in Swift. 一些函数式编程模式需要递归定义的类型,因此在Swift中使用它可能会很好。 At present, however, I am not sure one can usefully conform to a protocol with an associated type of the form T<Self> , even though the compiler allows its definition... otherwise, this should all just work at runtime. 但是,目前,我不确定即使编译器允许其定义也可以有效地符合具有相关类型T<Self>的协议……否则,这一切都应该在运行时起作用。

EDIT 2 编辑2

I have just upgraded to Xcode 6.1 GM Seed and things have changed! 我刚刚升级到Xcode 6.1 GM种子 ,情况已经改变! The following snippet, that would not have compiled before, now compiles and appears to run fine! 下面的代码段以前不会编译,现在可以编译并且运行正常!

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}

a.b = b         // --> {{{...}}}
b.a = a         // --> {{{...}}}

This improvement, however, does not extend to recursively defined associated types. 但是,此改进并未扩展到递归定义的关联类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM