Swift 使用关联类型和泛型时出错
下面的代码在第Swift 使用关联类型和泛型时出错,swift,Swift,下面的代码在第行返回p.foo(self)时给出了一个错误。错误显示:'P'没有名为'foo'的成员。 protocol P { typealias T func foo(c: C<T>) -> T func foo2() -> T } class C<T> { var p: P init (p: P) { self.p = p } func bar() -> T { return p.foo(self);
行返回p.foo(self)
时给出了一个错误。错误显示:'P'没有名为'foo'的成员。
protocol P {
typealias T
func foo(c: C<T>) -> T
func foo2() -> T
}
class C<T> {
var p: P
init (p: P) {
self.p = p
}
func bar() -> T {
return p.foo(self);
}
}
协议P{
别名T
func-foo(c:c)->T
func foo2()->T
}
C类{
var p:p
初始(p:p){
self.p=p
}
func bar()->T{
返回p.foo(self);
}
}
协议p
定义了一个关联类型,该类型应与任何专门的C类型正确匹配。我错过什么了吗?是否?来自:
协议本身并没有实现任何功能。尽管如此,您创建的任何协议都将成为在代码中使用的成熟类型
为了使用
.foo
方法,您需要一个结构
或类
来实现您的协议
您从未要求两个T
匹配。它们都在各自的范围内。因此,编译器会查找参数类型错误的foo
函数
我相信这样做是正确的:
protocol P {
typealias T
func foo<ConcreteP>(c: C<T, ConcreteP>) -> T
func foo2() -> T
}
class C<T, ConcreteP: P where T == ConcreteP.T> {
var p: ConcreteP
init (p: ConcreteP) {
self.p = p
}
func bar() -> T {
return p.foo(self);
}
}
这听起来像是一个编译器错误。在回答问题之前,我将对类型重命名一点,以使问题更清楚:
protocol P {
typealias ElementType
func foo(c: C<ElementType>) -> ElementType
func foo2() -> ElementType
}
class C<T> {
var p: P
init (p: P) {
self.p = p
}
func bar() -> T {
return p.foo(self)
}
}
这将消除初始值设定项的编译器错误。现在编译器知道参数必须是P的子类型,并且有效的子类型总是指定ElementType是什么,所以它很高兴
但这并不能帮你做到这一点:
var p: P
您仍然不能在此处使用不完整类型p
。您可能希望使用S
,但目前初始化器中的S
与您将用作变量类型的S之间没有联系,但它们显然需要相同。
是时候向类中引入第二个泛型参数了:
class C<T, S:P> {
var p: S
init (p: S) {
self.p = p
}
func bar() -> T {
return p.foo(self)
}
}
现在,我们指定由任何确认类型实现的foo函数实际上使用具有指定ElementType和实现类型本身的C。真想不到,不是吗
但我们还没有完全完成,最后一个错误仍然存在:
error: <EXPR>:13:18: error: cannot convert the expression's type 'T' to type 'S.ElementType'
return p.foo(self)
完整代码:
protocol P {
typealias ElementType
func foo(c: C<ElementType, Self>) -> ElementType
func foo2() -> ElementType
}
class C<T, S:P where S.ElementType == T> {
var p: S
init (p: S) {
self.p = p
}
func bar() -> T {
return p.foo(self);
}
}
协议P{
类型别名元素类型
func-foo(c:c)->ElementType
func foo2()->ElementType
}
C类{
var p:S
初始(p:S){
self.p=p
}
func bar()->T{
返回p.foo(self);
}
}
您是否尝试过使用mutating func而不仅仅是func?不太正确。您不必首先定义实现该协议的类或结构。在这种情况下,这甚至不能解决问题。根本问题是,P不能用作变量/参数的类型,因为它没有完全指定,因为缺少关联的类型。没有关联类型的协议应该可以工作。或者,指定变量必须是P的子类型也可以,正如我在回答中所做的那样。
class C<T, S:P> {
var p: S
init (p: S) {
self.p = p
}
func bar() -> T {
return p.foo(self)
}
}
func foo(c: C<ElementType>) -> ElementType
: type 'P' does not conform to protocol 'P'
func foo(c: C<ElementType, P>) -> ElementType
^
<EXPR>:2:15: note: associated type 'ElementType' prevents protocol from conforming to itself
typealias ElementType
protocol P {
typealias ElementType
func foo(c: C<ElementType, Self>) -> ElementType
func foo2() -> ElementType
}
error: <EXPR>:13:18: error: cannot convert the expression's type 'T' to type 'S.ElementType'
return p.foo(self)
class C<T, S:P where S.ElementType == T> {
protocol P {
typealias ElementType
func foo(c: C<ElementType, Self>) -> ElementType
func foo2() -> ElementType
}
class C<T, S:P where S.ElementType == T> {
var p: S
init (p: S) {
self.p = p
}
func bar() -> T {
return p.foo(self);
}
}