답변:
일반적 으로을 (를) 올바르게 처리하는 것을 제외하고로 ==라우팅합니다 . 참조 평등 (드물게 사용됨)은 입니다.equalsnulleq
3 == BigInt(3)와 BigInt(3) == 3사실이다. 그러나 사실 3.equals(BigInt(3))은 거짓 BigInt(3).equals(3)입니다. 따라서을 사용하는 것이 ==좋습니다. equals()스칼라에서는 사용하지 마십시오 . 나는 ==암묵적인 변환을 잘 한다고 생각 하지만 equals()그렇지 않습니다.
new java.lang.Integer(1) == new java.lang.Double(1.0)진정한 동안은 new java.lang.Integer(1) equals new java.lang.Double(1.0)거짓?
equals각 인스턴스의 컨텐츠를 비교하는 메소드를 대체하십시오 . 이것은 equalsJava에서 사용 된 것과 동일한 방법입니다==를 걱정하지 않고 연산자를 사용 하여 비교nulleq두 인수가 있는지 확인하는 방법을 정확하게 동일한 참조. 이것이 어떻게 작동하는지 이해하지 못하고 종종 equals대신 필요한 것에서 작동하지 않는 한 사용하지 않는 것이 좋습니다. 그리고 이것을 AnyRef인수가 아닌 인수 와 함께 사용해야합니다.Any참고 : 경우에 equals당신은 예를 들어이 인수 전환하면 바로 자바로,이 같은 결과를 반환하지 않을 수 있습니다 1.equals(BigInt(1))반환 false역 반환 곳을 true. 각 구현이 특정 유형 만 검사하기 때문입니다. 기본 숫자는 두 번째 인수가 유형이 아닌 다른 기본 유형 인지 확인하지 Number않습니다.BigInt
이 AnyRef.equals(Any)메소드는 서브 클래스로 대체 된 메소드입니다. 스칼라에 온 Java 스펙의 메소드. 박스가없는 인스턴스에서 사용되는 경우이를 호출하는 박스가 있습니다 (스칼라에는 숨겨져 있지만 Java에서는 int->가 더 분명합니다 Integer). 기본 구현은 단지 참조를 비교합니다 (Java와 동일).
이 Any.==(Any)메소드는 두 객체를 비교하고 두 인스턴스를 사용하여 정적 메소드를 호출하는 것처럼 두 인수를 모두 널로 허용합니다. 둘 다 인 경우를 비교 null한 다음 equals(Any)박스형 인스턴스 에서 메소드를 호출합니다 .
이 AnyRef.eq(AnyRef)방법은 참조, 즉 인스턴스가 메모리에있는 위치 만 비교 합니다 . 이 방법에 대한 암시 적 권투는 없습니다.
1 equals 2false로 리디렉션 될 때를 반환 합니다.Integer.equals(...)1 == 2false로 리디렉션 될 때를 반환 합니다.Integer.equals(...)1 eq 2 두 인수 모두 유형이어야하므로 컴파일되지 않습니다. AnyRefnew ArrayList() equals new ArrayList()true내용을 확인하면서를 반환 합니다.new ArrayList() == new ArrayList()true로 리디렉션 될 때를 반환 합니다.equals(...)new ArrayList() eq new ArrayList()false두 인수가 서로 다른 인스턴스이므로를 반환 합니다.foo equals foo반환 true하지 않는 foo것입니다 null, 다음을 던질 것이다NullPointerExceptionfoo == foo반환합니다 true경우에도 foo입니다nullfoo eq footrue두 인수가 동일한 참조에 연결되므로 가 반환됩니다.사이에 흥미로운 차이가 ==와 equals에 대한 Float및 Double유형 : 그들은 치료 NaN다르게 :
scala> Double.NaN == Double.NaN
res3: Boolean = false
scala> Double.NaN equals Double.NaN
res4: Boolean = true
편집 : 의견에서 지적했듯이 "이것은 Java에서도 발생합니다" 는 정확히 이것이 무엇인지에 달려 있습니다 .
public static void main(final String... args) {
final double unboxedNaN = Double.NaN;
final Double boxedNaN = Double.valueOf(Double.NaN);
System.out.println(unboxedNaN == unboxedNaN);
System.out.println(boxedNaN == boxedNaN);
System.out.println(boxedNaN.equals(boxedNaN));
}
이것은 인쇄됩니다
false
true
true
따라서 IEEE 부동 소수점 숫자가 그것을 정의하는 방식이기 때문에 평등과 비교할 때 의 unboxedNan수율 false은 모든 프로그래밍 언어에서 실제로 발생해야합니다 (어쨌든 정체성의 개념을 엉망으로 만듭니다).
박스형 NaN은 ==객체 참조를 비교할 때 Java를 사용한 비교에 적용됩니다.
이 경우에 대한 설명이 없습니다 equals.IMHO는 실제로 상자 ==가없는 이중 값 과 동일하게 작동해야 하지만 그렇지 않습니다.
스칼라로 번역하면 스칼라는 프리미티브와 객체 유형을 통합 Any하여 필요에 따라 프리미티브 더블과 박스형 더블로 변환 하기 때문에 조금 더 복잡 합니다. 따라서 스칼라 ==는 기본 NaN값 의 비교로 요약 되지만 equals박스형 Double 값에 정의 된 값을 사용합니다 (암시 적 변환 마술이 많이 진행되고 있으며으로 double에 포주가있는 물건이 있습니다 RichDouble).
실제로 무언가가 NaN사용되고 있는지 알아 내야하는 경우 isNaN: