你如何测试 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
类似地,如果您从一个字符串初始化另一个字符串,它们将共享相同的存储空间,直到其中一个发生变异(即字符串是写时复制)。
但是这些细节作为您不需要知道的实施细节对您是隐藏的。就语义而言,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
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
类似地,如果您从一个字符串初始化另一个字符串,它们将共享相同的存储空间,直到其中一个发生变异(即字符串是写时复制)。
但是这些细节作为您不需要知道的实施细节对您是隐藏的。就语义而言,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