定义具体的关联类型,但我仍然不能将协议用作变量
Defining concrete associatedtype but I still can't use protocol as variable
我想使用 SendMessageUseCase
作为变量类型,例如 var sendMessageUseCase: SendMessageUseCase
但我不能。
我一直收到错误 Protocol 'SendMessageUseCase' can only be used as a generic constraint because it has Self or associated type requirements
这显然是我理解的错误,但它没有意义。
在 SendMessageUseCase
中,我使用 Where
子句定义了我的关联类型,这意味着从技术上讲,编译器应该能够推断,因为我已经明确定义了 Input
和 Output
分别为 SendMessageUseCaseInput
和 SendMessageUseCaseOutput
。
protocol UseCaseInput {}
protocol UseCaseOutput {}
protocol UseCase : AnyObject {
associatedtype Input: UseCaseInput
associatedtype Output: UseCaseOutput
func execute(input: Input, _ completion: (_ output: Output) -> ())
}
struct SendMessageUseCaseInput : UseCaseInput {
var text: String
}
struct SendMessageUseCaseOutput: UseCaseOutput {
var response: String
}
protocol SendMessageUseCase: UseCase where Input == SendMessageUseCaseInput, Output == SendMessageUseCaseOutput {
}
final class TestSendMessageUseCase : SendMessageUseCase {
func execute(input: SendMessageUseCaseInput, _ completion: () -> ()) {
}
}
// Why this doesn't work?
var sendMessageUseCase: SendMessageUseCase = TestSendMessageUseCase()
SendMessageUseCase.Input
可以是除 SendMessageUseCaseInput
之外的任何其他内容吗?我不这么认为,这就是为什么我认为它应该被推断出来。但显然我错了,无法理解为什么。
感谢@Jessy 的评论,我找到了一个临时解决方案。
将 some
添加到 sendMessageUseCase
变量将允许我们使用 opaque
类型,但仍然存在限制,因为您不能拥有数组。
有一些会谈来实现这一点,但截至目前(2022 年 5 月 28 日)它仍未实现。
protocol UseCaseInput {}
protocol UseCaseOutput {}
protocol UseCase : AnyObject {
associatedtype Input: UseCaseInput
associatedtype Output: UseCaseOutput
func execute(input: Input, _ completion: (_ output: Output) -> ())
}
struct SendMessageUseCaseInput : UseCaseInput {
var text: String
}
struct SendMessageUseCaseOutput: UseCaseOutput {
var response: String
}
protocol SendMessageUseCase: UseCase where Input == SendMessageUseCaseInput, Output == SendMessageUseCaseOutput {
}
final class TestSendMessageUseCase : SendMessageUseCase {
func execute(input: SendMessageUseCaseInput, _ completion: (SendMessageUseCaseOutput) -> ()) {
}
}
var sendMessageUseCase: some SendMessageUseCase = TestSendMessageUseCase()
如果有人感兴趣,请查看论坛主题
Lifting the “Self or associated type” constraint on existentials
[[Sema]AST][WIP] Support existentials with concrete assoc. types #21576 (PR已关闭)
我想使用 SendMessageUseCase
作为变量类型,例如 var sendMessageUseCase: SendMessageUseCase
但我不能。
我一直收到错误 Protocol 'SendMessageUseCase' can only be used as a generic constraint because it has Self or associated type requirements
这显然是我理解的错误,但它没有意义。
在 SendMessageUseCase
中,我使用 Where
子句定义了我的关联类型,这意味着从技术上讲,编译器应该能够推断,因为我已经明确定义了 Input
和 Output
分别为 SendMessageUseCaseInput
和 SendMessageUseCaseOutput
。
protocol UseCaseInput {}
protocol UseCaseOutput {}
protocol UseCase : AnyObject {
associatedtype Input: UseCaseInput
associatedtype Output: UseCaseOutput
func execute(input: Input, _ completion: (_ output: Output) -> ())
}
struct SendMessageUseCaseInput : UseCaseInput {
var text: String
}
struct SendMessageUseCaseOutput: UseCaseOutput {
var response: String
}
protocol SendMessageUseCase: UseCase where Input == SendMessageUseCaseInput, Output == SendMessageUseCaseOutput {
}
final class TestSendMessageUseCase : SendMessageUseCase {
func execute(input: SendMessageUseCaseInput, _ completion: () -> ()) {
}
}
// Why this doesn't work?
var sendMessageUseCase: SendMessageUseCase = TestSendMessageUseCase()
SendMessageUseCase.Input
可以是除 SendMessageUseCaseInput
之外的任何其他内容吗?我不这么认为,这就是为什么我认为它应该被推断出来。但显然我错了,无法理解为什么。
感谢@Jessy 的评论,我找到了一个临时解决方案。
将 some
添加到 sendMessageUseCase
变量将允许我们使用 opaque
类型,但仍然存在限制,因为您不能拥有数组。
有一些会谈来实现这一点,但截至目前(2022 年 5 月 28 日)它仍未实现。
protocol UseCaseInput {}
protocol UseCaseOutput {}
protocol UseCase : AnyObject {
associatedtype Input: UseCaseInput
associatedtype Output: UseCaseOutput
func execute(input: Input, _ completion: (_ output: Output) -> ())
}
struct SendMessageUseCaseInput : UseCaseInput {
var text: String
}
struct SendMessageUseCaseOutput: UseCaseOutput {
var response: String
}
protocol SendMessageUseCase: UseCase where Input == SendMessageUseCaseInput, Output == SendMessageUseCaseOutput {
}
final class TestSendMessageUseCase : SendMessageUseCase {
func execute(input: SendMessageUseCaseInput, _ completion: (SendMessageUseCaseOutput) -> ()) {
}
}
var sendMessageUseCase: some SendMessageUseCase = TestSendMessageUseCase()
如果有人感兴趣,请查看论坛主题
Lifting the “Self or associated type” constraint on existentials
[[Sema]AST][WIP] Support existentials with concrete assoc. types #21576 (PR已关闭)