gpt4 book ai didi

swift - 身份运算符还可以检查命名类型是否相同,而不仅仅是引用相等

转载 作者:可可西里 更新时间:2023-11-01 01:22:36 26 4
gpt4 key购买 nike

据我了解,身份运算符用于确定两个对象是否具有相同的引用。这意味着,在实践中,运算符的两边都应该是一个对象。

但是,我尝试了下面的代码,它让我对我所理解的身份运算符的功能感到困惑

class Dog {}

let d: Dog = Dog()

if type(of: d) === Dog.self {
print("yep") //prints out "yep"
}

if type(of: d) == Dog.self {
print("yep") //prints out "yep"
}

恒等运算符的左右两边不是对象而是类型,就这一点而言,语义等价运算符和对象恒等运算符(看起来)似乎以相同的方式工作。

问题:

这是一个错误还是我没有正确理解整个要点。

感谢您的帮助和时间

最佳答案

The left and right side of the identity operator is not an object but a type.

实际上,在 Apple 平台上,它们对象。

这是因为 Swift 类在底层是作为 Objective-C 类实现的,正如 Mike Ash 详细介绍的那样 in this great blog post .这意味着类的元类型也是 Objective-C 类,因此符合AnyObject

因此,您可以将类元类型与标识运算符进行比较,因为它定义为:

public func ===(lhs: AnyObject?, rhs: AnyObject?) -> Bool

它将比较这两个对象是否是同一个对象,或者在本例中具体来说是同一个类元类型。

相反,在幕后,值类型 的元类型不是 Objective-C 对象——它只是指向某些静态元数据的指针。如果我们重写您的示例以使用 struct:

struct Dog {}

let d = Dog()

// Binary operator '===' cannot be applied to two 'Dog.Type' operands
if type(of: d) === Dog.self {
print("yep")
}

您会看到我们不能再使用 === 来比较元类型,因为它们不符合 AnyObject。所以实际上,使用恒等运算符来比较类元类型的能力只是它们作为 Objective-C 对象实现的副作用。

比较元类型的通用方法是使用相等运算符==,因为 Swift 专门为元类型提供了重载:

public func ==(t0: Any.Type?, t1: Any.Type?) -> Bool

这会检查两个元类型是否相同,但与 === 不同的是,它适用于两者 类元类型和值类型元类型。在引擎盖下,它已实现 as a simple pointer comparison ,因此应该始终产生与具有类元类型的 === 相同的结果。

因此,我总是建议将元类型与 == 进行比较,因为您不依赖于与 AnyObject 的一致性。例如,在 Linux 平台上,class metatypes don't conform to AnyObject因此不能与身份运算符进行比较(尽管有趣的是,当导入 Foundation 时,它似乎为 AnyObject.Type === 重载操作数——大概是为了帮助互操作性)。

关于swift - 身份运算符还可以检查命名类型是否相同,而不仅仅是引用相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43224682/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com