2015-07-21 47 views
2

假设我们有类Foo:Swift虚拟运营商?

class Foo { 
    // some variables 
} 

,我们有Foo类==操作符:

func ==(left: Foo, right: Foo) -> Bool { 
    return left.X == right.X && left.Y == right.Y && etc. 
} 

然后我们要在一些通用的功能

class func mergeUnique<T: Equatable>(workaround: T) -> ((data: [T], newData: [T]) -> [T]) { 
     return { (data: [T], newData: [T]) in 
      var res = data 
      for newElem in newData { 
       var duplicate = false 
       for oldElem in res { 
        if oldElem == newElem { 
         duplicate = true 
         break 
        } 
       } 

       if !duplicate { 
        res.append(newElem) 
       } 
      } 

      return res 
     } 
    } 

使用它问题是==运算符实际上是一个全局范围函数,而不是类方法(因为我们可以在C++中完成它),所以当函数接收到Equatable对象时,它使用E的==运算符quatable协议,而不是== Foo类的==操作符。在这种情况下,我需要类似虚拟行为的东西。有任何想法吗?

+2

你有没有试着让你的班级平衡:Foo类:Equatable? – Greg

回答

2

明确地定义你的类作为Equatable

extension Foo: Equatable {} 

func ==(left: Foo, right: Foo) -> Bool { 
    return awesomeEquatableLogic 
} 
+0

太好了。只需要在运营商实施之前添加'public',现在所有的工作都很好。对我来说不是非常明确的行为(与C++相比)。谢谢 – user3237732

+0

据我所知,你可以认为swift默认有虚拟方法。 'C++'的特殊性在于它试图始终执行静态分派(在编译时完成,因此需要将方法标记为“虚拟”),其中大多数其他面向对象的语言在运行时与消息传递一起工作。 – tomahh

+0

是的,C++的意识形态是'没有开销',所以默认的方法是非虚拟的,但标记为虚拟的方法的行为与Java或C#中的方法完全相同。对我来说不清楚的部分是快速==功能不是方法(我的意思不是成员函数)。但事实上它展示了虚拟行为并像方法一样工作。 – user3237732

2

你应该让你的类符合Equatable协议:

class Foo: Equatable { 
    ... 
} 

如果你不这样做,程序不知道如何检查为了平等,它将使用默认实现。 一旦你这样做,它将使用自定义==运算符。