如何比较"任何"值类型

the*_*end 19 swift

我有几个"Any"值类型,我想比较.

var any1: Any = 1
var any2: Any = 1

var any3: Any = "test"
var any4: Any = "test"

print(any1 == any2)
print(any2 == any3)
print(any3 == any4)
Run Code Online (Sandbox Code Playgroud)

使用==运算符会显示错误:

"二元运算符'=='不能应用于两个'Any'(又名'protocol <>')操作数"

这样做的方法是什么?

Aar*_*sen 27

执行此操作的唯一方法是使用除了==采用类型参数之外的函数,然后比较值,如果它们都是该类型:

func isEqual<T: Equatable>(type: T.Type, a: Any, b: Any) -> Bool {
    guard let a = a as? T, let b = b as? T else { return false }

    return a == b
}
Run Code Online (Sandbox Code Playgroud)

现在,使用上面的变量,您可以像这样比较它们:

var any1: Any = 1
var any2: Any = 1

var any3: Any = "test"
var any4: Any = "test"

isEqual(Int.self, a: any1, b: any2)      // true
isEqual(Int.self, a: any2, b: any3)      // false
isEqual(String.self, a: any3, b: any4)   // true
Run Code Online (Sandbox Code Playgroud)

  • @MichaelVoline 它在函数的第一行中使用。输入被转换为给定类型,如果其中一个失败,则它们被认为不相等。如果类型转换成功,则相等性由为该类型实现的 == 函数确定。关键是只有比较相同类型的两个值才有意义,因此我们必须首先验证它们是否是相同类型。但是,如果您没有为函数提供类型,那么唯一可能的实现就是类型转换为_every_类型,直到其中一个成功,这是不可能的 (2认同)

Ste*_*bua 6

你可以这样做AnyHashable

func equals(_ x : Any, _ y : Any) -> Bool {
    guard x is AnyHashable else { return false }
    guard y is AnyHashable else { return false }
    return (x as! AnyHashable) == (y as! AnyHashable)
}

print("\(equals(3, 4))")        // false
print("\(equals(3, equals))")   // false
print("\(equals(3, 3))")        // true
Run Code Online (Sandbox Code Playgroud)

由于不是每个Equatable都必须是Hashable,因此在极少数情况下这可能会失败。

通常没有理由使用上述 hack;但有时你会需要它,就像有时AnyHashable需要一样。