无法创建 sender/receiver 协议
Unable to create sender/receiver protocols
我有 2 个这样的协议:
protocol Receiver {
associatedtype Input
func send(_ input: Input)
}
protocol Sender {
associatedtype Output
init<T: Receiver>(_ receiver: T) where T.Input == Output
}
为了实现Sender
,我首先这样做:
class TestSender: Sender {
typealias Output = String
required init<T: Receiver>(_ receiver: T) where T.Input == Output {
}
}
但是我需要将 init
中的 receiver
存储为 class 属性。由于 Receiver
有关联的类型要求,我必须为整个 TestSender
class 添加泛型类型约束,像这样:
class TestSender<T: Receiver>: Sender where T.Input == String
然后我可以像这样在 TestSender
中声明一个 属性:
private let receiver: T
但在初始化程序中,我无法分配 receiver
。
required init<T: Receiver>(_ receiver: T) where T.Input == Output {
self.receiver = receiver // Cannot assign value of type 'T' to type 'T'
}
我尝试如下更改 init 方法:
init(_ receiver: T) {
self.receiver = receiver
}
但是现在,Swift 编译器说我没有正确遵守协议。做这样的事情的正确方法是什么?
解决方案
您可以使 Receiver
在 Sender
协议上有一个 associatedtype
,这样 Sender
在其 Receiver
上是通用的。
代码:
protocol Sender {
associatedtype InputReceiver: Receiver
associatedtype Output = InputReceiver.Input
init(_ receiver: InputReceiver)
}
class TestSender<T: Receiver>: Sender {
typealias Output = String
private let receiver: T
required init(_ receiver: T) {
self.receiver = receiver
}
}
为什么原始代码不起作用?
使用最新的代码,您应该会看到以下错误:
Type 'TestSender' does not conform to protocol 'Sender'
这表示某些要求未得到满足。如果单击 fix-it,则表明初始化程序存在问题。如果您再次单击修复,您又会遇到以下问题:
Cannot assign value of type 'T' to type 'T'
这是因为您在 TestSender
上有一个通用的 T
并且 在初始值设定项上也有一个通用的 T
。这些是不同的类型。
然而,忽略这一点,问题的根源在于:在你的 Sender
协议中,你只有 initializer 上的泛型,而在你的TestSender
class 您正在尝试在 class 本身上创建泛型。
要制定协议 'generic',您需要给它一个 associatedtype
。由于 Receiver
是通用的东西,它被用来创建 associatedtype
.
因为我们有 Receiver
泛型,所以我们也可以在 Sender
中得到 Output
类型。
希望你说得有道理,有什么问题可以问我(很难解释!)
我有 2 个这样的协议:
protocol Receiver {
associatedtype Input
func send(_ input: Input)
}
protocol Sender {
associatedtype Output
init<T: Receiver>(_ receiver: T) where T.Input == Output
}
为了实现Sender
,我首先这样做:
class TestSender: Sender {
typealias Output = String
required init<T: Receiver>(_ receiver: T) where T.Input == Output {
}
}
但是我需要将 init
中的 receiver
存储为 class 属性。由于 Receiver
有关联的类型要求,我必须为整个 TestSender
class 添加泛型类型约束,像这样:
class TestSender<T: Receiver>: Sender where T.Input == String
然后我可以像这样在 TestSender
中声明一个 属性:
private let receiver: T
但在初始化程序中,我无法分配 receiver
。
required init<T: Receiver>(_ receiver: T) where T.Input == Output {
self.receiver = receiver // Cannot assign value of type 'T' to type 'T'
}
我尝试如下更改 init 方法:
init(_ receiver: T) {
self.receiver = receiver
}
但是现在,Swift 编译器说我没有正确遵守协议。做这样的事情的正确方法是什么?
解决方案
您可以使 Receiver
在 Sender
协议上有一个 associatedtype
,这样 Sender
在其 Receiver
上是通用的。
代码:
protocol Sender {
associatedtype InputReceiver: Receiver
associatedtype Output = InputReceiver.Input
init(_ receiver: InputReceiver)
}
class TestSender<T: Receiver>: Sender {
typealias Output = String
private let receiver: T
required init(_ receiver: T) {
self.receiver = receiver
}
}
为什么原始代码不起作用?
使用最新的代码,您应该会看到以下错误:
Type 'TestSender' does not conform to protocol 'Sender'
这表示某些要求未得到满足。如果单击 fix-it,则表明初始化程序存在问题。如果您再次单击修复,您又会遇到以下问题:
Cannot assign value of type 'T' to type 'T'
这是因为您在 TestSender
上有一个通用的 T
并且 在初始值设定项上也有一个通用的 T
。这些是不同的类型。
然而,忽略这一点,问题的根源在于:在你的 Sender
协议中,你只有 initializer 上的泛型,而在你的TestSender
class 您正在尝试在 class 本身上创建泛型。
要制定协议 'generic',您需要给它一个 associatedtype
。由于 Receiver
是通用的东西,它被用来创建 associatedtype
.
因为我们有 Receiver
泛型,所以我们也可以在 Sender
中得到 Output
类型。
希望你说得有道理,有什么问题可以问我(很难解释!)