【发布时间】:2020-11-27 19:05:37
【问题描述】:
internal protocol Reducer {
associatedtype S : BaseState
associatedtype A : BaseAction
func reduce(state: S, action: A) -> S
}
internal class ReducerImpl : Reducer {
func reduce(state: MainState, action: MainAction) -> MainState { //<-- Error because MainAction is a protocol not a concrete one.
return state
}
}
internal class MainState : BaseState {}
internal protocol MainAction : BaseAction {}
internal protocol BaseState {}
internal protocol BaseAction {}
如果我将MainAction 从协议更改为类,编译错误就会消失。
我搜索了很多文章以了解此错误但失败了。
我必须在reduce(...) 函数中传递一个具体 参数(例如枚举、类、结构)吗?
我想让ReducerImpl可以采取各种符合MainAction的动作类型。
有没有人可以给我解释一下这个错误以及为什么 Swift 采用这种规则。
【问题讨论】:
-
这感觉像是一种非常精细的方式来表达一个简单的功能。你能举一个依赖这个协议的调用代码的例子吗?您需要“Base...”协议的事实表明您尝试使用协议重新发明类继承(以及您将其称为“子类型”的事实,这不是考虑需要其他协议的协议的好方法)。从调用代码和您尝试实现的算法开始,协议将随之而来。协议不是抽象类。它是一组带有语义的需求,允许你编写算法。
-
我越看这个,这个协议唯一可能的(纯粹的,非崩溃的)实现是ReducerImpl。使用
action参数实际上是不可能的。我知道您已经简化了问题的内容,但是当您删除了问题的要点时,就会出现问题。不可能将此协议用于有用的目的,这表明您已删除将提供答案的部分。 -
您需要什么
BaseState和BaseState?我假设 reducer 可以对多种数据类型进行操作,因此将它们都限制在一个通用协议中以便在 reducer 中使用它似乎是不可行的。放弃这两个Base协议,它们带来的问题比解决的问题多。
标签: swift