实现泛型协议方法,但对整个 class 使用泛型

Implement generic protocol method with but use generic for whole class

我正在尝试实现一个具有泛型参数的协议方法,但随后将泛型类型用于我的整个 class 而不是仅在方法上使用,类似这样

protocol FirstProtocol {
}

protocol SecondProtocol {
    func foo<T: FirstProtocol>(argument: T)
}

class MyType<T: FirstProtocol>: SecondProtocol {
    var value: T? = nil
    func foo<T>(argument: T) {
        value = argument     // ERROR: Cannot assign value of type 'T' to type 'T?'
    }
}

所以 swift 编译器接受 foo<T>(argument:T) 匹配 SecondProtocol 的方法,如果我注释掉错误行它编译正常,但它不会让我分配 argumentvalue 即使 valueargument 应该相同类型,编译器抱怨好像它们是不同的类型。

it will not let me assign argument to value even though value and argument should be the same type, the compiler complains as if they are different types.

想想这个案例:

class答:第一个协议{ }

class B: FirstProtocol { }

class A 和 B 是 func foo(argument: T){} 可接受的泛型类型,但是您可以将 class A 的实例分配给 class B 吗?

class MyType<T: FirstProtocol>: SecondProtocol

删除“: FirstProtocol”应该可以,或者使用基础 class 替换 FirstProtocol

argumentvalue的类型确实是不同的类型。 foo 中的 T 泛型参数只是一个标识符,我可以将其更改为其他任何内容:

class MyType<T: FirstProtocol>: SecondProtocol {
    var value: T? = nil
    func foo<AnythingElse>(argument: AnythingElse) {
        // MyType still conforms to SecondProtocol
    }
}

foo中的T是一个全新的通用参数,不同于MyType中的T。他们恰好同名。

请注意,当您声明泛型方法时,决定泛型类型的是 调用者,而不是泛型方法。 foo 在这里想说的是 "I want the T in foo to be the same type as the T in MyType",但它不能说它自己的通用参数!

修复它的一种方法是使 SecondProtocol 具有关联类型:

protocol SecondProtocol {
    // name this properly!
    associatedtype SomeType: FirstProtocol
    func foo(argument: SomeType)
}

class MyType<T: FirstProtocol>: SecondProtocol {
    typealias SomeType = T // here is where it says "I want 'SomeType' to be the same type as 'T'!"
    var value: T? = nil
    func foo(argument: T) {
        value = argument
    }
}