你如何使用多种类型参数 - Swift 2?

时间:2015-12-08 22:10:19

标签: swift generics types parameters

我正在尝试编写一个通用的中介基类(Mediator),它将对等类注册到在实例化时定义的特定协议(在对等类扩展上)。

Mediator和Peer子类不应该彼此了解。他们的关系是在所有人都接通的时候定义的。这是为了使每个组件模块化。

如果我只使用一个类型参数,例如:

class Mediator<T, U> {
    private var peers = [T]()
    func registerPeer(peer: T) {
        self.peers.append(peer)
    }
}

然后一个Peer正确注册。

我希望T或U都可以附加到peer []。

我正在寻找一种解决方案,只修改Mediator的peer []和registerPeer()以允许混合或T或U.

// Mediator
class Mediator<T, U> {

// I want this to be an Array that can be T OR U
private var peers = Array<T|U>()

// I want peer: to be either T OR U
func registerPeer(peer: <T|U>) {

    self.peers.append(peer)
    }
}

class RootModuleMediator<T, U> : Mediator<T, U> {}

protocol RootModuleMediatorsIOInterface { func someFunction() }
extension RootModuleMediator : RootModuleMediatorsIOInterface { func  someFunction() { print("RootModuleMediator someFunction() printed")}}
protocol RootModuleMediatorsViewInterface { func aFunction() }
extension RootModuleMediator : RootModuleMediatorsViewInterface { func aFunction() { print("RootModuleMediator aFunction() printed")}}

// Peer
class Peer<T> {

    private var mediator : T?
    func registerMediator(mediator: T) { self.mediator = mediator }

}

// View Peer
class RootModuleView<T> : Peer<T> {}
protocol RootModuleViewsMediatorInterface { func someFunction() }
extension RootModuleView : RootModuleViewsMediatorInterface { func someFunction() { print("RootModuleView someFunction() printed") }}

// IO Peer
class RootModuleIO<T> : Peer<T> {}
protocol RootModuleIOsMediatorInterface { func someFunction() }
extension RootModuleIO : RootModuleIOsMediatorInterface { func someFunction() { print("RootModuleIO  someFunction() printed") }}

// Wiring components together
let rootModuleIO = RootModuleIO<RootModuleMediatorsIOInterface>()
let rootModuleView = RootModuleView<RootModuleMediatorsViewInterface>()

let rootModuleMediator = RootModuleMediator<RootModuleIOsMediatorInterface, RootModuleViewsMediatorInterface>()

rootModuleIO.registerMediator(rootModuleMediator)
rootModuleView.registerMediator(rootModuleMediator)

rootModuleMediator.registerPeer(rootModuleIO)
rootModuleMediator.registerPeer(rootModuleView)

// I want the following function to print "RootModuleIO  someFunction() printed"
rootModuleMediator.peers[0].someFunction()

3 个答案:

答案 0 :(得分:1)

我没有看到其余的实现来验证它是否会按预期工作,但你的意思是这样的:

class Mediator<T, U> {
    private var peers = [(T, U)]()

    func registerPeer(peer: (T, U)) {
        self.peers.append(peer)
    }

    func registerPeer(left: T, _ right: U) {
        registerPeer((left, right))
    }

}

缺少的步骤是使用tuples作为数组元素。

答案 1 :(得分:0)

可以使用符合多种协议的泛型类型。它是这样完成的:

class Mediator<T where T: RootModuleMediatorsIOInterface, T: RootModuleIOsMediatorInterface> {

    private var peers = Array<T>()

    func registerPeer(peer: T) {

        self.peers.append(peer)
    }

    func exercisePeers() {
        for peer in peers {
            peer.someFunction()
            peer.someOtherFunction()
        }
    }
}

class RootModuleMediator : RootModuleMediatorsIOInterface, RootModuleIOsMediatorInterface {}


// ############ EXAMPLE PROTOCOL CONSTRAINED EXTENSIONS IMPLEMENTATION ############


protocol RootModuleMediatorsIOInterface { func someFunction() }

extension RootModuleMediatorsIOInterface { func someFunction() { print("Something")}}

protocol RootModuleIOsMediatorInterface { func someOtherFunction() }

extension RootModuleIOsMediatorInterface { func someOtherFunction() { print("Something else") }}

let root = RootModuleMediator()
let mediator = Mediator<RootModuleMediator>()

mediator.registerPeer(root)
mediator.exercisePeers()

我添加了一个练习功能,因此您可以看到您可以调用协议扩展实现的功能。我还简化了您的协议​​和扩展定义。输出正如您所期望的那样:

Something
Something else

答案 2 :(得分:0)

最后,我无法使用T或U类型参数来处理数组或函数。相反,选择了更适合我松散耦合组件并使它们通过定义的接口进行通信的用例的解决方案。

// Mediator base
class Mediator<IOTypeParam, ViewTypeParam> {

    private var IO : IOTypeParam?
    private var view : ViewTypeParam?

    func registerIOPeer(peer: IOTypeParam) { self.IO = peer }
    func registerViewPeer(peer: ViewTypeParam) { self.view = peer }

}

// Mediator subclass
class RootModuleMediator<IOTypeParam, ViewTypeParam> : Mediator<IOTypeParam, ViewTypeParam> {}

protocol RootModuleMediatorsIOInterface { func someFunction() }
extension RootModuleMediator : RootModuleMediatorsIOInterface { func someFunction() { print("RootModuleMediator someFunction() printed")}}
protocol RootModuleMediatorsViewInterface { func aFunction() }
extension RootModuleMediator : RootModuleMediatorsViewInterface { func aFunction() { print("RootModuleMediator aFunction() printed")}}

// Peer base
class Peer<MediatorTypeParam> {

    private var mediator : MediatorTypeParam?
    func registerMediator(mediator: MediatorTypeParam) { self.mediator = mediator }

}

// View Peer
class RootModuleView<MediatorTypeParam> : Peer<MediatorTypeParam> {}
protocol RootModuleViewsMediatorInterface { func someFunction() }
extension RootModuleView : RootModuleViewsMediatorInterface { func someFunction() { print("RootModuleView someFunction() printed") }}

// IO Peer
class RootModuleIO<MediatorTypeParam> : Peer<MediatorTypeParam> {}
protocol RootModuleIOsMediatorInterface { func someFunction() }
extension RootModuleIO : RootModuleIOsMediatorInterface { func someFunction() { print("RootModuleIO  someFunction() printed") }}

// Instances
let rootModuleIO = RootModuleIO<RootModuleMediatorsIOInterface>()
let rootModuleView = RootModuleView<RootModuleMediatorsViewInterface>()
let rootModuleMediator = RootModuleMediator<RootModuleIOsMediatorInterface, RootModuleViewsMediatorInterface>()

// Interface registration
rootModuleIO.registerMediator(rootModuleMediator)
rootModuleView.registerMediator(rootModuleMediator)
rootModuleMediator.registerIOPeer(rootModuleIO)
rootModuleMediator.registerViewPeer(rootModuleView)

// Communication constrained to defined interfaces
rootModuleMediator.IO!.someFunction()
rootModuleMediator.view!.someFunction()
rootModuleIO.mediator!.someFunction()
rootModuleView.mediator!.aFunction()