【问题标题】:Swift virtual operator?Swift 虚拟运算符?
【发布时间】:2015-07-21 13:07:26
【问题描述】:

假设我们有 Foo 类:

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 对象时,它使用 Equatable 协议的 == 运算符,而不是 Equatable 协议的 == 运算符福班。在这种情况下,我需要类似虚拟行为的东西。有什么想法吗?

【问题讨论】:

  • 你有没有尝试让你的班级平等:class Foo: Equatable ?

标签: swift oop


【解决方案1】:

将你的类明确定义为Equatable

extension Foo: Equatable {}

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

【讨论】:

  • 太棒了。只需在操作员实施之前添加public,现在一切正常。对我来说不是很清楚的行为(与 C++ 相比)。谢谢
  • 据我了解,您可以认为 swift 默认具有虚拟方法。 C++ 的特殊性在于它总是尝试进行静态调度(在编译时完成,因此需要将方法标记为virtual),而大多数其他面向对象的语言在运行时处理消息传递。
  • 是的,C++ 理念是“无开销”,因此默认方法是非虚拟的,但标记为虚拟的方法的行为与 Java 或 C# 中的方法完全相同。我不清楚的部分是 swift 中的 == 函数不是方法(我的意思是不是成员函数)。但事实上它展示了虚拟行为并且像方法一样工作。
【解决方案2】:

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

class Foo: Equatable {
    ...
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-08
    • 2021-11-12
    • 2019-10-21
    • 2012-12-02
    • 2012-12-03
    • 2010-10-14
    • 2020-09-20
    相关资源
    最近更新 更多