两个类或结构的通用函数

时间:2014-08-23 01:58:09

标签: generics swift

在我正在进行的项目中,我有两个不同的类,ArrayMatrix。我想在这些类上应用函数实现Array -> ArrayMatrix -> Matrix

我目前有

func f(x: Array) -> Array{
    return x+1 // generic but is not always this simple
}
func f(x: Matrix) -> Matrix{
    return x+1
}

如何创建一个接受这两个类的函数?我看过依赖Equatable和其他内置协议的例子,但我只想使用这两个类。

2 个答案:

答案 0 :(得分:0)

尝试:

func f<T>(x: T) -> T {
    return x + 1
}

答案 1 :(得分:0)

你需要定义一个泛型函数,就像Gary Makin所描述的那样,但它可以为编译器提供更多关于传入内容的信息。你要做的是定义一个描述类成员的协议/您将在函数中使用的/ methods /运算符,然后扩展ArrayMatrix以符合该协议。最后,您将该协议添加为泛型函数的约束,并且编译器将理解只有符合该协议的类型(Array和Matrix现在可以使用的类型)才能与该函数一起使用,并且一切都将有效。

以下是两个简单自定义类MyTypeOne和MyTypeTwo的示例。它们每个都有一个私有实例变量counter(在一个中定义为Int,另一个定义为Double)和incrementBy方法,其中Int并递增内部计数器。不是很有用,但它们有助于说明上述要点:

struct MyTypeOne {
    var counter: Int = 0
    mutating func incrementBy(amt: Int) {
        counter += amt
    }
}
struct MyTypeTwo {
    var counter: Double = 0.0
    mutating func incrementBy(amt: Int) {
        counter += Double(amt)
    }
}

我有一个函数f(),我希望能够使用任何一种类型调用 - 我将把它作为通用实现:

func f<T>(var x: T) -> T {
    x.incrementBy(1)
    return x
}

不幸的是,编译器抱怨'T' does not have a member named 'incrementBy'。拯救的协议!

protocol MyIncrementable {
    mutating func incrementBy(amt: Int)
}

extension MyTypeOne : MyIncrementable { }
extension MyTypeTwo : MyIncrementable { }

MyTypeOneMyTypeTwo的扩展是空的,因为它们已经实现了协议 - 这些扩展只是向编译器声明了实现。最后,我们准备用协议约束来更新我们的通用函数:

func f<T: MyIncrementable>(var x: T) -> T {
    x.incrementBy(1)
    return x
}

希望这有帮助!