子协议类型的Swift协议一致性问题

时间:2020-07-24 16:18:49

标签: swift

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(...)函数中传递 concrete 参数(例如,枚举,类,结构)吗?

我想让ReducerImpl可以采取各种符合MainAction的动作类型。

有人可以给我解释一下该错误以及Swift为何采用这种规则。

1 个答案:

答案 0 :(得分:2)

associatedtype必须是具体的,即。 类型而不是协议

您可以做的是使用可以接受MainAction参数的泛型函数创建更窄的协议:

internal protocol MainReducer {
    associatedtype State
    func reduce<Action>(state: State, action: Action) -> State where Action: MainAction
}

internal class ReducerImpl: MainReducer {
    func reduce<Action>(state: MainState, action: Action) -> MainState where Action: MainAction {
        return state
    }
}