3

Swift 和其他一些语言一样,有一个恒等运算符===。但似乎你不能对字符串使用它:

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

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

4

1 回答 1

5

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

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

但是这些细节对你来说是隐藏的,因为你不应该知道这些细节。就语义而言,s1完全s2不相关。

如果您担心性能,则底层 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
于 2015-05-25T17:06:50.717 回答