在我正在进行的项目中,我有两个不同的类,Array
和Matrix
。我想在这些类上应用函数实现Array -> Array
或Matrix -> 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和其他内置协议的例子,但我只想使用这两个类。
答案 0 :(得分:0)
尝试:
func f<T>(x: T) -> T {
return x + 1
}
答案 1 :(得分:0)
你需要定义一个泛型函数,就像Gary Makin所描述的那样,但它可以为编译器提供更多关于传入内容的信息。你要做的是定义一个描述类成员的协议/您将在函数中使用的/ methods /运算符,然后扩展Array
和Matrix
以符合该协议。最后,您将该协议添加为泛型函数的约束,并且编译器将理解只有符合该协议的类型(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 { }
MyTypeOne
和MyTypeTwo
的扩展是空的,因为它们已经实现了协议 - 这些扩展只是向编译器声明了实现。最后,我们准备用协议约束来更新我们的通用函数:
func f<T: MyIncrementable>(var x: T) -> T {
x.incrementBy(1)
return x
}
希望这有帮助!