Reputation: 20590
Why can't the === be used with String's in Swift? I am unable to compile the following:
let string1 = "Bob"
let string2 = "Fred"
if string1 === string2 {
...
}
and get the following error (on the if line):
Binary operator '===' cannot be applied to two 'String' operands
What I want to be able to do in my unit tests is, having performed a copyWithZone:, verify that two objects are indeed a different object with different pointers even if their values are the same. The following code doesn't work...
XCTAssertFalse(object1.someString === object2.someString)
If anyone knows of an alternative way please advise.
Upvotes: 6
Views: 3753
Reputation: 62052
Swift's ===
operator, by default, is only defined for classes.
Swift's String
type is not a class but a struct. It does not inherit from AnyObject
and therefore cannot be compared by reference.
You could of course implement an ===
operator for String
in Swift, but I'm not sure how it would be any different from the implementation of ==
for Swift's String
type.
func ===(lhs: String, rhs: String) -> Bool {
return lhs == rhs
}
Unless, of course, you really wanted to compare the references, I suppose you could do something like this:
func ===(lhs: String, rhs: String) -> Bool {
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
}
However, for the sake of tests, rather than using the ==
or ===
operators, you should use the appropriate assertions:
XCTAssertEqual(foo, bar)
XCTAssertNotEqual(foo, bar)
Upvotes: 5
Reputation: 70097
Swift Strings are value type, not reference type, so there's no need for that, a copy will always be a different object.
You should just compare by value with ==
.
Upvotes: 2
Reputation: 42588
If you try really hard, you can force things to happen, but I'm not sure what that buys you.
class MyClass: NSObject, NSCopying {
var someString: NSString = ""
required override init() {
super.init()
}
func copyWithZone(zone: NSZone) -> AnyObject {
let copy = self.dynamicType.init()
copy.someString = someString.copy() as? NSString ?? ""
return copy
}
}
let object1 = MyClass()
object1.someString = NSString(format: "%d", arc4random())
let object2 = object1.copy()
if object1.someString === object2.someString {
print("identical")
} else {
print("different")
}
prints identical
, the system is really good at conserving strings.
Upvotes: 0
Reputation: 2002
The === operator is the identity operator. It checks if two variables or constants refer to the same instance of a class. Strings are not classes (they are structs) so the === operator does not apply to them.
If you want to check if two strings are the same, use the equality operator == instead.
Read all about the identity operator in the Swift documentation.
You can just check two objects for identity directly, instead of checking a property of type String.
XCTAssertFalse(object1 === object2)
Upvotes: 3
Reputation: 52530
string1 and string2 are not NSString, but String. Since they are value objects, not reference objects, there is no reference that could be compared with ===.
Upvotes: 8