==와 ===의 차이점
신속하게 두 개의 항등 연산자가있는 것 같습니다 : double equals ( ==
) 및 triple equals ( ===
), 둘 사이의 차이점은 무엇입니까?
한마디로 :
==
연산자는 인스턴스 값이 같은지 확인합니다. "equal to"
===
연산자는 참조가 동일한 인스턴스를 가리키는 지 확인합니다. "identical to"
긴 답변 :
클래스는 참조 유형이며, 여러 상수 및 변수가 배후에서 클래스의 동일한 단일 인스턴스를 참조 할 수 있습니다. 클래스 참조는 런타임 스택 (RTS)에 유지되고 해당 인스턴스는 메모리의 힙 영역에 유지됩니다. 동일성을 제어하면 ==
인스턴스가 서로 같은지 여부를 의미합니다. 같은 인스턴스 일 필요는 없습니다. 이를 위해 사용자 정의 클래스에 평등 기준을 제공해야합니다. 기본적으로 사용자 정의 클래스 및 구조에는 "같음"연산자 ==
및 "같지 않음 "연산자로 알려진 동등 연산자의 기본 구현이 수신 되지 않습니다 !=
. 이를 위해서는 커스텀 클래스가 Equatable
프로토콜 을 준수해야하며 static func == (lhs:, rhs:) -> Bool
기능
예를 보자.
class Person : Equatable {
let ssn: Int
let name: String
init(ssn: Int, name: String) {
self.ssn = ssn
self.name = name
}
static func == (lhs: Person, rhs: Person) -> Bool {
return lhs.ssn == rhs.ssn
}
}
P.S.:
ssn (사회 보장 번호)은 고유 한 번호이므로 이름이 같은지 비교할 필요가 없습니다.
let person1 = Person(ssn: 5, name: "Bob")
let person2 = Person(ssn: 5, name: "Bob")
if person1 == person2 {
print("the two instances are equal!")
}
person1 및 person2 참조는 힙 영역에서 서로 다른 두 인스턴스를 가리 키지 만 ssn 숫자가 같기 때문에 인스턴스가 동일합니다. 따라서 출력은the two instance are equal!
if person1 === person2 {
//It does not enter here
} else {
print("the two instances are not identical!")
}
===
연산자는 참조가 동일한 인스턴스를 가리키는 지 확인합니다 "identical to"
. person1과 person2는 힙 영역에 서로 다른 두 개의 인스턴스가 있으므로 동일하지 않고 출력이 다릅니다.the two instance are not identical!
let person3 = person1
P.S:
클래스는 참조 유형이며 person1의 참조는이 할당 조작으로 person3에 복사되므로 두 참조 모두 힙 영역에서 동일한 인스턴스를 가리 킵니다.
if person3 === person1 {
print("the two instances are identical!")
}
그들은 동일하며 출력은 the two instances are identical!
!==
및 ===
신원 연산자이며, 두 물체가 동일한 부호를 가지고 있는지 확인하기 위해 사용된다.
Swift는 두 개의 ID 연산자 (=== 및! ==)도 제공하는데, 두 개의 객체 참조가 모두 동일한 객체 인스턴스를 참조하는지 여부를 테스트하는 데 사용합니다.
발췌 : Apple Inc.“Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l
두 오브젝티브 C 및 신속한에서, ==
및 !=
숫자 값 값 어떤지 연산자 시험 (예를 들어, NSInteger
, NSUInteger
, int
, 및 목표-C에서 Int
, UInt
등 신속한에서). 개체 (NSObject의 /의 NSNumber 및 서브 오브젝티브 C 및 신속한 참조 유형) 내용 ==
과 !=
즉, 동일한 해시 값 - - 또는 각각 같은 동일한 것이 아니다 개체 / 참조 형식이 동일한 동일한 것이 있는지 테스트 .
let a = NSObject()
let b = NSObject()
let c = a
a == b // false
a == c // true
Swift의 항등 항등 연산자 ===
및 !==
참조 항등 검사-따라서 항등 항등 연산자 IMO 라고합니다 .
a === b // false
a === c // true
Swift의 사용자 정의 참조 유형 (Equatable을 준수하는 클래스를 서브 클래스 화하지 않음)은 연산자와 동일하게 자동으로 구현되지 않지만 ID 동등성 연산자는 여전히 적용됨을 지적 할 가치가 있습니다. 또한를 구현 ==
하면 !=
자동으로 구현됩니다.
class MyClass: Equatable {
let myProperty: String
init(s: String) {
myProperty = s
}
}
func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return lhs.myProperty == rhs.myProperty
}
let myClass1 = MyClass(s: "Hello")
let myClass2 = MyClass(s: "Hello")
myClass1 == myClass2 // true
myClass1 != myClass2 // false
myClass1 === myClass2 // false
myClass1 !== myClass2 // true
이러한 동등 연산자는 어느 언어의 구조와 같은 다른 유형에 대해서도 구현되지 않습니다. 그러나 Swift에서 사용자 지정 연산자를 만들 수 있습니다. 예를 들어 CGPoint가 동일한 지 확인하는 연산자를 만들 수 있습니다.
infix operator <==> { precedence 130 }
func <==> (lhs: CGPoint, rhs: CGPoint) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
let point1 = CGPoint(x: 1.0, y: 1.0)
let point2 = CGPoint(x: 1.0, y: 1.0)
point1 <==> point2 // true
스위프트 3 이상
===
(또는 !==
)
- 값이 동일한 지 확인 합니다 (둘 다 동일한 메모리 주소를 가리킴) .
- 참조 유형 비교 .
==
Obj-C 에서처럼 (포인터 평등).
==
(또는 !=
)
- 값이 같은지 확인합니다 .
- 값 유형 비교 .
isEqual:
Obj-C 동작 의 기본값과 같습니다 .
여기서는 세 가지 인스턴스를 비교합니다 (클래스는 참조 유형입니다).
class Person {}
let person = Person()
let person2 = person
let person3 = Person()
person === person2 // true
person === person3 // false
===
단순한 포인터 산술을 넘어서는 스위프트에는 미묘한 점이 있습니다 . 오브젝티브 C에 어떤 두 개의 포인터 (즉 비교할 수 있었지만 NSObject *
포함) ==
이 유형은 컴파일시 훨씬 더 큰 역할을하기 때문에 더 이상 사실 스위프트에 없습니다.
놀이터는 당신에게 줄 것이다
1 === 2 // false
1 === 1 // true
let one = 1 // 1
1 === one // compile error: Type 'Int' does not conform to protocol 'AnyObject'
1 === (one as AnyObject) // true (surprisingly (to me at least))
문자열을 사용하면 다음에 익숙해 져야합니다.
var st = "123" // "123"
var ns = (st as NSString) // "123"
st == ns // true, content equality
st === ns // compile error
ns === (st as NSString) // false, new struct
ns === (st as AnyObject) // false, new struct
(st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch")
NSString(string:st) === NSString(string:st) // false, new structs
var st1 = NSString(string:st) // "123"
var st2 = st1 // "123"
st1 === st2 // true
var st3 = (st as NSString) // "123"
st1 === st3 // false
(st as AnyObject) === (st as AnyObject) // false
그러나 다음과 같이 재미를 가질 수도 있습니다.
var st4 = st // "123"
st4 == st // true
st4 += "5" // "1235"
st4 == st // false, not quite a reference, copy on write semantics
나는 당신이 훨씬 더 재미있는 경우를 생각할 수 있다고 확신합니다 :-)
Swift 3 업데이트 (Jakub Truhlář의 의견에서 제안한대로)
1===2 // Compiler error: binary operator '===' cannot be applied to two 'Int' operands
(1 as AnyObject) === (2 as AnyObject) // false
let two = 2
(2 as AnyObject) === (two as AnyObject) // false (rather unpleasant)
(2 as AnyObject) === (2 as AnyObject) // false (this makes it clear that there are new objects being generated)
이것은 좀 더 일관성과 같습니다 Type 'Int' does not conform to protocol 'AnyObject'
그러나 우리가 다음 수,
type(of:(1 as AnyObject)) // _SwiftTypePreservingNSNumber.Type
그러나 명백한 전환은 어떤 일이있을 수 있음을 분명히합니다. String 쪽에서는 NSString
우리가 사용할 수있는 한 계속 사용할 수 있습니다 import Cocoa
. 그럼 우리는
var st = "123" // "123"
var ns = (st as NSString) // "123"
st == ns // Compile error with Fixit: 'NSString' is not implicitly convertible to 'String'; did you mean to use 'as' to explicitly convert?
st == ns as String // true, content equality
st === ns // compile error: binary operator '===' cannot be applied to operands of type 'String' and 'NSString'
ns === (st as NSString) // false, new struct
ns === (st as AnyObject) // false, new struct
(st as NSString) === (st as NSString) // false, new structs, bridging is not "free" (as in "lunch")
NSString(string:st) === NSString(string:st) // false, new objects
var st1 = NSString(string:st) // "123"
var st2 = st1 // "123"
st1 === st2 // true
var st3 = (st as NSString) // "123"
st1 === st3 // false
(st as AnyObject) === (st as AnyObject) // false
두 개의 String 클래스를 갖는 것은 여전히 혼란 스럽지만 암시 적 변환을 삭제하면 조금 더 눈에 잘 띄게됩니다.
예를 들어 클래스의 두 인스턴스를 만드는 경우 myClass
:
var inst1 = myClass()
var inst2 = myClass()
해당 인스턴스를 비교할 수 있습니다.
if inst1 === inst2
인용 :
두 객체 참조가 모두 동일한 객체 인스턴스를 참조하는지 테스트하는 데 사용합니다.
발췌 : Apple Inc.“Swift Programming Language.” iBooks. https://itun.es/sk/jEUH0.l
Swift에는 === simbol이 있는데 이는 두 객체가 동일한 참조 동일한 주소를 참조한다는 것을 의미합니다
class SomeClass {
var a: Int;
init(_ a: Int) {
self.a = a
}
}
var someClass1 = SomeClass(4)
var someClass2 = SomeClass(4)
someClass1 === someClass2 // false
someClass2 = someClass1
someClass1 === someClass2 // true
Any
객체 와 관련된 약간의 기여 .
나는 단위 테스트로 일하고 있었고 NotificationCenter
, Any
평등을 비교하고 싶은 매개 변수로 사용 했습니다.
그러나 Any
평등 작업에는 사용할 수 없으므로 변경해야했습니다. 궁극적으로, 나는 다음과 같은 접근 방식에 정착하여 특정 상황에서 평등을 얻을 수 있었으며 여기에 간단한 예가 나와 있습니다.
func compareTwoAny(a: Any, b: Any) -> Bool {
return ObjectIdentifier(a as AnyObject) == ObjectIdentifier(b as AnyObject)
}
이 함수는 ObjectIdentifier를 활용 하여 객체에 고유 한 주소를 제공하므로 테스트 할 수 있습니다.
ObjectIdentifier
위의 링크에서 Apple 당 참고해야 할 항목 하나 :
Swift에서는 클래스 인스턴스와 메타 타입 만 고유 한 ID를 갖습니다. 구조체, 열거 형, 함수 또는 튜플에 대한 동일성 개념은 없습니다.
==
두 변수가 같은지 확인하는 데 사용됩니다 2 == 2
. 그러나 ===
동등의 경우, 즉 클래스의 경우 동일한 객체 예제를 참조하는 두 인스턴스가 많은 경우 다른 많은 인스턴스가 보유하는 참조가 작성됩니다.
스위프트 4 : 단위 테스트 를 사용한 또 다른 예 는 ===에서만 작동합니다.
참고 : 아래 테스트는 ==에서 실패하고 ===에서 작동합니다.
func test_inputTextFields_Delegate_is_ViewControllerUnderTest() {
//instantiate viewControllerUnderTest from Main storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
viewControllerUnderTest = storyboard.instantiateViewController(withIdentifier: "StoryBoardIdentifier") as! ViewControllerUnderTest
let _ = viewControllerUnderTest.view
XCTAssertTrue(viewControllerUnderTest.inputTextField.delegate === viewControllerUnderTest)
}
그리고 수업은
class ViewControllerUnderTest: UIViewController, UITextFieldDelegate {
@IBOutlet weak var inputTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
inputTextField.delegate = self
}
}
==를 사용하는 경우 단위 테스트의 오류는 Binary operator '==' cannot be applied to operands of type 'UITextFieldDelegate?' and 'ViewControllerUnderTest!'
가치 평등
- 목표 -C :
isEqual:
- 빠른:
==
- 목표 -C :
참조 평등
- 목표 -C :
==
- 빠른:
===
- 목표 -C :
자세한 내용은 여기
참고 URL : https://stackoverflow.com/questions/24002819/difference-between-and
'Programing' 카테고리의 다른 글
PHP + MySQL 트랜잭션 예제 (0) | 2020.03.21 |
---|---|
부트 스트랩 4-Glyphicons 마이그레이션? (0) | 2020.03.21 |
계속하기 전에 JavaScript 휴면 / 대기 (0) | 2020.03.21 |
AngularJS에서 속성을 조건부로 적용하는 가장 좋은 방법은 무엇입니까? (0) | 2020.03.21 |
Lisp 매크로를 그렇게 특별하게 만드는 것은 무엇입니까? (0) | 2020.03.21 |