你如何测试 Swift 中字符串的身份?

How do you test the identity of Strings in Swift?

Swift,像其他一些语言一样,有一个身份运算符 ===。但似乎你不能将它用于字符串:

var x = "hello"
var y = "hello"
if x === y {         //ERROR: 'String' does not conform to protocol 'AnyObject'
    println("SAME!")
}else {
    println("DIFFERENT!")
}

是否没有直接的方法来测试字符串的身份?!...还是我遗漏了什么?

Swift 中的字符串是值类型而不是引用类型。也就是说,它们只有价值,没有身份。从这个意义上说,检查两个字符串是否具有相同的“身份”是没有意义的。除非它们是相同的变量,否则它们是不同的。相反,您应该使用 ==.

检查它们是否具有相同的值

幕后可能有实习。其实肯定有:

struct StringBits {
    let underlyingPtr: UnsafeMutablePointer<Void>
    let padding1: UnsafeMutablePointer<Void>
    let padding2: UnsafeMutablePointer<Void>
}

let s1 = "abcd"
let s2 = "abcd"

let bits1 = unsafeBitCast(s1, StringBits.self)
let bits2 = unsafeBitCast(s2, StringBits.self)

println(bits1.underlyingPtr) //      0x0000000117654000
println(bits2.underlyingPtr) // also 0x0000000117654000

类似地,如果您从一个字符串初始化另一个字符串,它们将共享相同的存储空间,直到其中一个发生变异(即字符串是写时复制)。

但是这些细节作为您不需要知道的实施细节对您是隐藏的。就语义而言,s1s2 完全无关。

如果您关心性能,底层 String 类型可能会使用指向其存储的指针,以在它们共享相同存储的情况下有效地检查是否相等。数组(实现方式类似)可以,如下所示:

struct NeverEqual: Equatable { }

// NOT a correct implementation of ==, since == must be
// reflexive, and this isn’t:
func ==(lhs: NeverEqual, rhs: NeverEqual)->Bool { return false }

let x=[NeverEqual()]
let y=x

// this returns true – because it doesn’t bother comparing the 
// elements, because it knows x and y share the same storage
x==y