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

时间:2015-05-25 16:52:34

标签: swift operators identity-operator

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

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

是否没有直接的方法来测试字符串的身份?!...或者我错过了什么?

1 个答案:

答案 0 :(得分:4)

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