如何通过泛型减少样板代码

问题描述 投票:0回答:1

符合通用协议的结构体很少:

protocol StateMachineState {...}

struct VideoMode: StateMachineState {    
    func transit(state: PhotoMode) -> Transition? {
        return Transition(targetState: state)
    }
}

struct PhotoMode: StateMachineState {    
    func transit(state: VideoMode) -> Transition? {
        return Transition(targetState: state)
    }
}

以及此类成员方法的用法:

func transit(target_state: PhotoMode) {
    process(transition: state.transit(state: target_state))
}

func transit(target_state: VideoMode) {
    process(transition: state.transit(state: target_state))
}

注意,所有

func transit()
都有相同的实现,它们仅在参数类型上有所不同。
VideoMode
PhotoMode
都符合相同的协议。目标是减少代码重复并尝试应用泛型?编写一个通用函数,接受所有符合通用协议的类型。我假设
state.transit(...)
调用需要具体类型 -
VideoMode
PhotoMode
以某种方式进行识别...类似:

func transit<Mode: StateMachineState>(target_state: Mode) {     // Mode equals StateMachineState
    try process(transition: state.transit(state: target_state)) // Requires VideMode or PhotoMode
}

代码报告“对实例方法transit的调用不完全匹配”,并分别使用VideoMode

PhotoMode
为候选者提供服务。

有没有办法使用泛型让编译器自己生成重复的方法,或者我必须自己编写和重复(主体总是相同的)?

(我来自 C++ 世界,这是非常常见的技术,但在 Swift 中我很难让它编译和运行......)

swift generics polymorphism
1个回答
0
投票
由于您没有提供完整的代码,我必须做出一些假设,但是......

    无需一一确认协议。您可以为协议编写扩展:
extension StateMachineState { func transit<Other: StateMachineState>(state: Other) -> Transition? { return Transition(targetState: state) } }
(假设您的 

Transition

 类型支持此)

    现在,假设
  1. state
     不是 StateMachineState 的具体实现,你可以这样做:
class SomeType<SMS: StateMachineState> { var state: SMS func transit<Other: StateMachineState>(target_state: Other) { try process(transition: state.transit(state: target_state)) } }
这样,您在实现过程中就不会使用具体类型,并且可以从 process() 参数访问协议上的扩展方法。

© www.soinside.com 2019 - 2024. All rights reserved.