Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:重写子类中的==结果仅在超类中调用==_Swift_Overriding_Equality - Fatal编程技术网

Swift:重写子类中的==结果仅在超类中调用==

Swift:重写子类中的==结果仅在超类中调用==,swift,overriding,equality,Swift,Overriding,Equality,我有一个类a,它符合equalable协议并实现=函数。在子类BI中,使用更多检查覆盖= 但是,当我在B的两个实例数组(它们都具有类型Array)之间进行比较时,会调用A的=。当然,如果我将两个数组的类型都更改为Array,则调用B的= 我提出了以下解决方案: A.swift: internal func ==(lhs: A, rhs: A) -> Bool { if lhs is B && rhs is B { return lhs as! B

我有一个类
a
,它符合
equalable
协议并实现
=
函数。在子类
B
I中,使用更多检查覆盖
=

但是,当我在
B
的两个实例数组(它们都具有类型
Array
)之间进行比较时,会调用
A
=
。当然,如果我将两个数组的类型都更改为
Array
,则调用
B
=

我提出了以下解决方案:

A.swift:

internal func ==(lhs: A, rhs: A) -> Bool {
    if lhs is B && rhs is B {
        return lhs as! B == rhs as! B
    }
    return ...
}

它看起来非常难看,必须对
A
的每个子类进行扩展。有没有办法确保首先调用子类的
=

对于
数组和更多信息调用
a
的等式的原因

天真的解决方案可能是在
a
中定义一个动态调度函数,然后定义
=
来调用它:

class A: Equatable {
    func equalTo(rhs: A) -> Bool {
        // whatever equality means for two As
    }
}

func ==(lhs: A, rhs: A) -> Bool {
    return lhs.equalTo(rhs)
}
然后,当您实现
B
时,您将覆盖
equalTo

class B: A {
    override func equalTo(rhs: A) -> Bool {
        return (rhs as? B).map { b in
            return // whatever it means for two Bs to be equal
        } ?? false   // false, assuming a B and an A can’t be Equal
    }
}
你仍然必须像跳舞一样做一个
,因为你需要确定右边的参数是否是a
B
(如果
equalTo
直接接受a
B
,它就不是合法的覆盖)

这里还隐藏着一些可能令人惊讶的行为:

let x: [A] = [B()]
let y: [A] = [A()]

// this runs B’s equalTo
x == y
// this runs A’s equalTo
y == x
也就是说,参数的顺序会改变行为。这并不好——人们期望平等是对称的。所以你真的需要上面链接中描述的一些技术来正确地解决这个问题

在这一点上,你可能会觉得这一切都变得有点不必要了。特别是在Swift标准库中的
equalable
文档中给出了以下注释:

相等意味着可替代性。当
x==y
x
y
在任何只取决于其值的代码中都是可互换的

类实例标识由三个相等值区分
==
是 值得注意的是,它不是实例值的一部分。暴露其他非价值 不鼓励
equalable
类型的方面,以及 应在文件中明确指出暴露的问题


有鉴于此,如果实现相等的方式不是两个相等的值被彼此替换,那么您可能会认真地重新考虑对
equalable
实现的喜爱。避免这种情况的一种方法是将对象标识看作是平等的度量,并在===/COD>中实现<代码>=< /代码>,这只需要为超级类做一次。或者,您可以问自己,您真的需要实现继承吗?如果不是,请考虑放弃它并使用值类型,然后使用协议和泛型来捕获您正在寻找的多态行为。

我遇到了类似的问题,因为我想在MKPoPANTANTITY子类上使用<代码>差异(从:)/代码>(继承自NSObjor)。即使我将

func==
添加到我的注释子类中,
difference(from:
仍然会调用NSObject的
=
实现。我相信这只是比较了两个对象的内存位置,这不是我想要的(from:
正常工作,我必须实现
覆盖函数isEqual(\uObject:Any?)->Bool{
用于我的注释子类。在正文中,我会确保
对象
与我的子类的类型相同,然后在那里进行比较。

非常感谢详细的回答和您的辛勤工作!稍后我将查看链接。另一个问题:如果
扩展中声明了
equalable
协议一致性
,您不能覆盖它。