实现相同协议的不同结构的重载函数?

时间:2016-09-25 19:00:31

标签: swift generics overloading

我是静态类型语言的新手,并想知道是否可以将Struct转换为其类型以调用正确的重载函数?我遇到的问题是我有一个符合Mutation协议的Structs列表。我想迭代列表并为每个Struct调用正确的handle函数。我可以将这个handle函数移动到Struct本身,但是对于我试图实现的API,我想看看是否可以这样做:

//: Playground - noun: a place where people can play

import UIKit

protocol Mutation {
    func mutate(state: Int) -> Int
}

struct CountIncrement: Mutation {
    func mutate(state: Int) -> Int {
        return state + 1
    }
}

struct CountDecrement: Mutation {
    func mutate(state: Int) -> Int {
        return state - 1
    }
}

func handle(mutation: CountIncrement, state: Int) -> Int {
    print("WILL INCREMENT")
    return mutation.mutate(state: state)
}

func handle(mutation: CountDecrement, state: Int) -> Int {
    print("WILL DECREMENT")
    return mutation.mutate(state: state)
}

var state = 0
var queue = [CountIncrement(), CountDecrement()] as [Mutation]

for mutation in queue {
    handle(mutation: mutation, state: state) // error: cannot invoke 'handle' with an argument list of type '(mutation: Mutation, state: Int)'
}

2 个答案:

答案 0 :(得分:1)

您可以合并handle()这样的函数,并接受参数mutation符合您的协议Mutation的所有对象:

func handle(mutation: Mutation, state: Int) -> Int {
    return mutation.mutate(state: state)
}

原因是:

queue属于[Mutating]类型。因此,您的for-Loop中的mutation将为Mutation。目前,您没有handle()函数,它接受Mutation作为参数。

答案 1 :(得分:1)

这是你应该如何解决问题的倒退。在Swift中,您通常应该避免使用自由函数(例如-56dp),而是将方法附加到类型。

你的循环想要一个特定的方法,所以你想要一个新的协议(你当然可以将这个功能附加到handle(mutation:state:),但是将它分开意味着它可以有不同的访问控制等,所以就像灵活的自由功能)。

Mutation

所以我们刚刚声明你想要的这个功能就是一个东西。现在我们可以将它附加到我们关心的事物上。这与您在上面编写自由函数完全相同。它是相同的模式。语法不同,并提供了一些关于此函数存在的额外文档,并允许IDE更有效地提供自动完成和收集文档。

protocol MutationHandling {
    func handleMutation(forState state: Int) -> Int
}

现在,您将此特殊协议用于您的列表:

extension CountIncrement: MutationHandling {
    func handleMutation(forState state: Int) -> Int {
        print("WILL INCREMENT")
        return mutate(state: state)
    }
}

并称之为:

var queue = [CountIncrement(), CountDecrement()] as [MutationHandling]

这不仅仅是Swift中的一些随机限制。这是Swift如何分解问题的重要部分。明确不鼓励使用自由函数(参见API Design Guidelines)。方法和扩展是Swift方式。