equal?, eql?, === 및 ==의 차이점은 무엇입니까?
저는 이 네 가지 방법의 차이를 이해하려고 노력하고 있습니다.는 기본적으로 그것을 알고 있습니다.==
를 메드를호출다니합서▁the라고 부릅니다.equal?
두 피연산자가 정확히 동일한 객체를 참조할 때 true를 반환합니다.
===
으로 " 적으또호다니합출한로기본"도 합니다.==
어느 쪽인가 하면equal?
좋아요, 그럼 이 세 가지 방법이 모두 무시되지 않는다면, 제 생각엔===
,==
그리고.equal?
정확히 같은 일을 합니까?
이제 옵니다.eql?
이것은 무엇을 합니까(기본값)?피연산자의 해시/ID로 전화를 걸 수 있습니까?
루비는 왜 이렇게 많은 등호를 가지고 있습니까?그들은 의미론적으로 달라야 합니까?
여기서는 개체 설명서를 크게 인용하겠습니다. 이 설명서에는 몇 가지 훌륭한 설명이 포함되어 있다고 생각하기 때문입니다.String과 같은 다른 클래스에서 재정의되므로 이 메소드에 대한 설명서도 읽어 보시기 바랍니다.
참고: 다른 개체에서 직접 사용해 보고 싶다면 다음과 같은 방법을 사용하십시오.
class Object
def all_equals(o)
ops = [:==, :===, :eql?, :equal?]
Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
end
end
"a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false}
==
"호인"
에서 개수준
==
다음 경우에만 true를 반환합니다.obj
그리고.other
동일한 개체입니다.일반적으로 이 메서드는 하위 클래스에서 재정의되어 클래스별 의미를 제공합니다.
이것은 가장 일반적인 비교이며, 따라서 클래스의 작성자인 사용자가 두 개체가 "동일"한지 여부를 결정할 수 있는 가장 기본적인 위치입니다.
===
평등
Object, 는 객체클래경호사출동실일다니합상과우의스다▁object동을 호출하는 것과 .
#==
그러나 일반적으로 하위 항목에 의해 재정의되어 사례 문에 의미 있는 의미론을 제공합니다.
이것은 매우 유용합니다.로운 점이 의 예===
구현:
- 범위
- 정규 표현식
- Proc(Ruby 1.9 버전)
따라서 다음과 같은 작업을 수행할 수 있습니다.
case some_object
when /a regex/
# The regex matches
when 2..4
# some_object is in the range 2..4
when lambda {|x| some_crazy_custom_predicate }
# the lambda returned true
end
여기서 제 답변을 참조하여 방법의 깔끔한 예를 확인하십시오.case
+Regex
코드를 훨씬 더 깨끗하게 만들 수 있습니다.그리고 물론, 당신의 것을 제공함으로써.===
사용자 정의 구현, 자용지정을 수 .case
의미론
eql?
—Hash
그
eql?
가 true를 반환하면 합니다.obj
그리고.other
동일한 해시 키를 참조합니다.은 다음과 같이 사용됩니다.Hash
구성원의 평등성을 테스트합니다.클래스 객체의 경우 는 와 동의어입니다. 하위 클래스는 일반적으로 에일리어스를 사용하여 이 전통을 이어갑니다.eql?
그들이 무시하는 대로.==
방법입니다. 그러나 예외가 있습니다.Numeric
를 들어, type은 예를들어, 변환수행에서 type 합니다.==
그러나 건너편은 아닌eql?
그래서:1 == 1.0 #=> true 1.eql? 1.0 #=> false
그래서 당신은 당신 자신의 용도를 위해 이것을 자유롭게 재정의할 수 있습니다. 아니면 당신은 그것을 재정의할 수 있습니다.==
및사를 합니다.alias :eql? :==
따라서 두 가지 방법은 동일한 방식으로 작동합니다.
equal?
비교
와는과 다르게 .
==
,equal?
는 안 됩니다. 하는 데 사용됩니다.a.equal?(b)
만약에a
는 와동개체니다입한과 같은 입니다.b
).
이것은 효과적으로 포인터 비교입니다.
저는 jtbandes 답변을 좋아하지만, 꽤 길기 때문에 저만의 간결한 답변을 추가하겠습니다.
==
,===
,eql?
,equal?
Ruby에서 4개의 비교기, 즉 2개의 객체를 비교하는 4가지 방법입니다.
Ruby에서 모든 비교기(및 대부분의 연산자)는 실제로 메서드 호출이므로 이러한 비교 방법의 의미를 직접 변경, 덮어쓰기 및 정의할 수 있습니다.그러나 Ruby의 내부 언어 구조가 다음 중 어떤 비교기를 사용하는지 이해하는 것이 중요합니다.
==
비교으)로 표시)
Ruby는 :==를 모든 곳에서 사용하여 두 개체의 값을 비교합니다.해시 값:
{a: 'z'} == {a: 'Z'} # => false
{a: 1} == {a: 1.0} # => true
===
비교 (사례)
Ruby는 case/message 시 : ===를사용합다니construct/▁case다▁ruby니.다음 코드 스니펫은 논리적으로 동일합니다.
case foo
when bar; p 'do something'
end
if bar === foo
p 'do something'
end
eql?
키 (해시 키)
루비는 : eql?(메소드 해시와 함께)을 사용하여 해시 키를 비교합니다.대부분의 클래스:eql?은(는):==과(와) 동일합니다.
:대한 한 클래스를 eql?에 대한 지식입니다.
class Equ
attr_accessor :val
alias_method :initialize, :val=
def hash() self.val % 2 end
def eql?(other) self.hash == other.hash end
end
h = {Equ.new(3) => 3, Equ.new(8) => 8, Equ.new(15) => 15} #3 entries, but 2 are :eql?
h.size # => 2
h[Equ.new(27)] # => 15
참고: 일반적으로 사용되는 Ruby-class Set도 해시 키 비교에 의존합니다.
equal?
비교객체 ID 비교)
동등하다고요?합니다.두 개체가 동일한지 확인합니다.클래스 BasicObject의 이 메서드는 덮어쓸 수 없습니다.
obj = obj2 = 'a'
obj.equal? obj2 # => true
obj.equal? obj.dup # => false
등호 연산자: == 및 !=
동일 또는 이중 등호라고도 하는 == 연산자는 두 개체가 동일하면 true를 반환하고 그렇지 않으면 false를 반환합니다.
"koan" == "koan" # Output: => true
!= 연산자(부등식이라고도 함)는 ==의 반대입니다.두 개체가 동일하지 않으면 true를 반환하고 동일하면 false를 반환합니다.
"koan" != "discursive thought" # Output: => true
순서가 같은 요소를 가진 두 배열은 동일하지 않으며, 동일한 문자의 대소문자 버전은 동일하지 않습니다.
서로 다른 유형(예: 정수 및 부동)의 숫자를 비교할 때 숫자 값이 같으면 ==이 true를 반환합니다.
2 == 2.0 # Output: => true
동등합니까?
두 피연산자가 동일한지 테스트하는 == 연산자와 달리, 동일한 방법은 두 피연산자가 동일한 개체를 참조하는지 확인합니다.이것은 루비에서 가장 엄격한 평등의 형태입니다.
예: a = "zen" b = "zen"
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120
a.equal? b # Output: => false
위의 예에서는 동일한 값을 가진 두 개의 문자열이 있습니다.그러나 개체 ID가 서로 다른 두 개의 별개 개체입니다.따라서 equal? 메서드는 false를 반환합니다.
다시 시도해 보겠습니다. 이번에만 b가 a에 대한 참조가 될 것입니다.개체 ID는 두 변수가 동일한 개체를 가리키므로 두 변수 모두에 대해 동일합니다.
a = "zen"
b = a
a.object_id # Output: => 18637360
b.object_id # Output: => 18637360
a.equal? b # Output: => true
eql?
해시 클래스에서 eql? 메서드는 키의 동일성을 테스트하는 데 사용됩니다.이것을 설명하기 위해서는 약간의 배경이 필요합니다.컴퓨팅의 일반적인 맥락에서 해시 함수는 임의의 크기의 문자열(또는 파일)을 사용하여 일반적으로 유일한 해시라고 하는 고정 크기의 문자열 또는 정수를 생성합니다.일반적으로 사용되는 일부 해시 코드 유형은 MD5, SHA-1 및 CRC입니다.암호화 알고리즘, 데이터베이스 인덱싱, 파일 무결성 검사 등에 사용됩니다.Ruby와 같은 일부 프로그래밍 언어는 해시 테이블이라는 컬렉션 유형을 제공합니다.해시 테이블은 고유한 키와 해당 값으로 구성된 쌍으로 데이터를 저장하는 사전과 유사한 컬렉션입니다.후드 아래에 해당 키는 해시 코드로 저장됩니다.해시 테이블은 일반적으로 단순 해시라고 합니다.해시라는 단어가 어떻게 해시 코드 또는 해시 테이블을 나타낼 수 있는지 주목합니다.루비 프로그래밍의 맥락에서 해시라는 단어는 거의 항상 사전과 같은 모음을 가리킵니다.
Ruby는 해시 코드를 생성하기 위한 해시라는 기본 제공 방법을 제공합니다.아래 예제에서는 문자열을 사용하고 해시 코드를 반환합니다.동일한 값을 가진 문자열이 서로 다른 개체(개체 ID가 다름)일지라도 항상 동일한 해시 코드를 갖는 방식에 주목합니다.
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
"meditation".hash # Output: => 1396080688894079547
해시 메서드는 모든 Ruby 개체의 기본 루트인 Object 클래스에 포함된 커널 모듈에 구현됩니다.Symbol 및 Integer와 같은 일부 클래스는 기본 구현을 사용하고 String 및 Hash와 같은 다른 클래스는 자체 구현을 제공합니다.
Symbol.instance_method(:hash).owner # Output: => Kernel
Integer.instance_method(:hash).owner # Output: => Kernel
String.instance_method(:hash).owner # Output: => String
Hash.instance_method(:hash).owner # Output: => Hash
Ruby에서, 우리가 해시(수집)에 무언가를 저장할 때, 키로 제공된 객체(예: 문자열 또는 기호)가 해시 코드로 변환되어 저장됩니다.나중에 해시(수집)에서 요소를 검색할 때 객체를 키로 제공하여 해시 코드로 변환하여 기존 키와 비교합니다.일치하는 항목이 있으면 해당 항목의 값이 반환됩니다.비교는 후드 아래의 eql? 방법을 사용하여 수행됩니다.
"zen".eql? "zen" # Output: => true
# is the same as
"zen".hash == "zen".hash # Output: => true
대부분의 경우 eql? 방법은 == 방법과 유사하게 작동합니다.하지만 몇 가지 예외가 있습니다.예를 들어, eql?은 정수를 플로트와 비교할 때 암시적 형식 변환을 수행하지 않습니다.
2 == 2.0 # Output: => true
2.eql? 2.0 # Output: => false
2.hash == 2.0.hash # Output: => false
대/소문자 구분 연산자: ===
String, Range, Regexp와 같은 Ruby의 기본 제공 클래스는 대소문자 구분, 삼중 동등 또는 3퀄이라고도 하는 === 연산자의 자체 구현을 제공합니다.클래스마다 다르게 구현되므로 호출된 개체의 유형에 따라 다르게 동작합니다.일반적으로 오른쪽에 있는 개체가 왼쪽에 있는 개체에 속하거나 "구성원"이면 true가 반환됩니다.예를 들어 개체가 클래스의 인스턴스(또는 해당 하위 클래스 중 하나)인지 테스트하는 데 사용할 수 있습니다.
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
작업에 가장 적합한 다른 방법에서도 동일한 결과를 얻을 수 있습니다.일반적으로 효율성과 간결성을 희생하지 않고 가능한 한 명시적으로 코드를 쉽게 작성하는 것이 좋습니다.
2.is_a? Integer # Output: => true
2.kind_of? Integer # Output: => true
2.instance_of? Integer # Output: => false
2와 같은 정수는 정수 클래스의 하위 클래스인 Fixnum 클래스의 인스턴스이기 때문에 false가 반환된 마지막 예제입니다.===는 _a? 및 instance_의 것입니까?메서드는 개체가 지정된 클래스 또는 하위 클래스의 인스턴스인 경우 true를 반환합니다.instance_of 메서드는 더 엄격하며 개체가 하위 클래스가 아닌 해당 클래스의 인스턴스인 경우에만 true를 반환합니다.
의 종류는 무엇입니까?메서드는 객체 클래스에 의해 혼합된 커널 모듈에 구현됩니다.둘 다 동일한 메서드의 별칭입니다.확인해 보겠습니다.
kernel.instance_method(:kind_of?)kernel.instance_method(: is_a?) # 출력: => true
===의 범위 구현
=== 연산자가 범위 개체에 대해 호출되면 오른쪽의 값이 왼쪽의 범위 내에 있으면 true가 반환됩니다.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false
("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
=== 조작자가 왼쪽 개체의 === 메서드를 호출합니다.그래서 (1..=== 3은 (1...4)와 같습니다.3. 즉, 좌측 피연산자의 클래스는 호출될 === 방법의 구현을 정의하므로 피연산자 위치는 서로 교환할 수 없습니다.
===의 Regexp 구현
오른쪽 문자열이 왼쪽 정규식과 일치하면 true를 반환합니다. /zen/ === "practice zazen today" # 출력: => true # 는 "practice zazen today" = ~ /zen/
사례/시점에 대한 === 연산자의 암묵적인 사용
이 연산자는 대/시 문장의 후드 아래에서도 사용됩니다.그것이 가장 일반적인 용도입니다.
minutes = 15
case minutes
when 10..20
puts "match"
else
puts "no match"
end
# Output: match
위의 예에서 Ruby가 암묵적으로 이중 등호 연산자(==)를 사용했다면 범위는 10입니다.20은 15와 같은 정수로 간주되지 않습니다.삼중 등호 연산자(===)가 모든 경우/when 문에 암시적으로 사용되므로 일치합니다.위 예제의 코드는 다음과 같습니다.
if (10..20) === minutes
puts "match"
else
puts "no match"
end
패턴 매칭 연산자 : =~, !~
=~ (bang-tilde) 및 !~ (bang-tilde) 연산자는 정규식 패턴에 대해 문자열과 기호를 일치시키는 데 사용됩니다.
String 및 Symbol 클래스에서 =~ 메서드를 구현하려면 정규식(Regexp 클래스의 인스턴스)을 인수로 사용해야 합니다.
"practice zazen" =~ /zen/ # Output: => 11
"practice zazen" =~ /discursive thought/ # Output: => nil
:zazen =~ /zen/ # Output: => 2
:zazen =~ /discursive thought/ # Output: => nil
Regexp 클래스의 구현에서는 문자열 또는 기호를 인수로 사용해야 합니다.
/zen/ =~ "practice zazen" # Output: => 11
/zen/ =~ "discursive thought" # Output: => nil
모든 구현에서 문자열 또는 기호가 Regexp 패턴과 일치하면 일치하는 위치(인덱스)인 정수를 반환합니다.일치하는 항목이 없으면 0을 반환합니다.Ruby에서 임의의 정수 값은 "truthy"이고 nil은 "fruthy"이므로 if 문 및 3진 연산자에서 =~ 연산자를 사용할 수 있습니다.
puts "yes" if "zazen" =~ /zen/ # Output: => yes
"zazen" =~ /zen/?"yes":"no" # Output: => yes
패턴 일치 연산자는 if 문을 더 짧게 작성하는 데도 유용합니다.예:
if meditation_type == "zazen" || meditation_type == "shikantaza" || meditation_type == "kinhin"
true
end
Can be rewritten as:
if meditation_type =~ /^(zazen|shikantaza|kinhin)$/
true
end
!~ 연산자는 =~와 반대이며, 일치하는 항목이 없으면 true를 반환하고 일치하는 항목이 있으면 false를 반환합니다.
자세한 내용은 이 블로그 게시물에서 확인할 수 있습니다.
』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』 『 』===
교환입니다.
===
등호 연산자가 아닙니다!
것은 아니다.
그 점을 정말로 이해합시다.
은 당은잘알있것다입니을고신▁be에 익숙할 수도 .===
자바스크립트와 PHP의 동등 연산자로, 그러나 이것은 루비의 동등 연산자가 아니며 근본적으로 다른 의미를 가지고 있습니다.
그서어쩌죠래?는 입니까?===
하십니까?
===
패턴 매칭 연산자입니다!
===
합니다.===
membership을 합니다.===
의 검사의 입니다.===
합니다.===
평등을 은 그렇지 .
그렇다면 이 광기가 어떻게 말이 됩니까?
Enumerable#grep
사용하다===
case when
은 문사를 사용합니다.===
- 재미있는 사실은,
rescue
사용하다===
그렇기 때문에 정규식, 클래스 및 범위, 심지어 람다 식을 사용할 수 있습니다.case when
진술.
몇 가지 예
case value
when /regexp/
# value matches this regexp
when 4..10
# value is in range
when MyClass
# value is an instance of class
when ->(value) { ... }
# lambda expression returns true
when a, b, c, d
# value matches one of a through d with `===`
when *array
# value matches an element in array with `===`
when x
# values is equal to x unless x is one of the above
end
는 이모예다같작이동다니합음과는든▁with다▁work▁all니작합동▁these와 함께 작동합니다.pattern === value
마찬가지로grep
방법.
arr = ['the', 'quick', 'brown', 'fox', 1, 1, 2, 3, 5, 8, 13]
arr.grep(/[qx]/)
# => ["quick", "fox"]
arr.grep(4..10)
# => [5, 8]
arr.grep(String)
# => ["the", "quick", "brown", "fox"]
arr.grep(1)
# => [1, 1]
Ruby는 동일성을 처리하기 위한 몇 가지 다른 방법을 제공합니다.
a.equal?(b) # object identity - a and b refer to the same object
a.eql?(b) # object equivalence - a and b have the same value
a == b # object equivalence - a and b have the same value with type conversion.
아래 링크를 클릭하여 계속 읽으세요, 그것은 저에게 명확한 요약 이해를 주었습니다.
https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/equality-matchers
다른 사람들에게 도움이 되길 바랍니다.
#--- 대소문자 동일
#--- 일반적인 동일성
둘 다 비슷하게 작동하지만 "==="는 사례 설명도 합니다.
"test" == "test" #=> true
"test" === "test" #=> true
여기서의 차이
String === "test" #=> true
String == "test" #=> false
- .eql? - 이 연산자는 수신기와 인수의 유형과 값이 모두 같으면 true를 반환합니다.
예를 들어 - 10.eql?(10.0)은 거짓입니다.
- - 사례 문장에서 동일성을 테스트합니다.
예를 들어 - (1...10) === 1은 참입니다.
- - 이 연산자는 주어진 두 피연산자가 동일한지 여부를 확인합니다.같으면 TRUE를 반환하고 그렇지 않으면 FALSE를 반환합니다.
예를 들어 - (1...10) == 1은 거짓입니다.
위의 모든 것에 대해 간단한 테스트를 작성했습니다.
def eq(a, b)
puts "#{[a, '==', b]} : #{a == b}"
puts "#{[a, '===', b]} : #{a === b}"
puts "#{[a, '.eql?', b]} : #{a.eql?(b)}"
puts "#{[a, '.equal?', b]} : #{a.equal?(b)}"
end
eq("all", "all")
eq(:all, :all)
eq(Object.new, Object.new)
eq(3, 3)
eq(1, 1.0)
언급URL : https://stackoverflow.com/questions/7156955/whats-the-difference-between-equal-eql-and
'programing' 카테고리의 다른 글
Ruby 'require' 오류: 해당 파일을 로드할 수 없습니다. (0) | 2023.05.31 |
---|---|
워크시트 기반 확인란 선택 여부 확인 (0) | 2023.05.31 |
Flexbox 항목 간의 거리를 설정하려면 어떻게 해야 합니까? (0) | 2023.05.31 |
Eclipse 오류: 필요한 .class 파일에서 간접적으로 참조됩니까? (0) | 2023.05.31 |
Ruby에서 파일 경로에서 확장자 없이 파일 이름을 가져오는 방법 (0) | 2023.05.31 |