내가 말할 때 { :bla => 1, :bloop => 2 }
정확히 무엇을 :
합니까? 문자열과 어떻게 비슷한 지, 어떻게 든 기호에 대해 읽었습니다.
나는 그 개념에 대해 명확하지 않다. 누군가 나를 밝힐 수 있을까?
내가 말할 때 { :bla => 1, :bloop => 2 }
정확히 무엇을 :
합니까? 문자열과 어떻게 비슷한 지, 어떻게 든 기호에 대해 읽었습니다.
나는 그 개념에 대해 명확하지 않다. 누군가 나를 밝힐 수 있을까?
답변:
:foo
"foo"라는 기호입니다. 기호에는 동일한 이름의 두 기호가 동일하다는 특징이 있습니다.
"foo".equal? "foo" # false
:foo.equal? :foo # true
이렇게하면 두 기호를 정말 빠르게 비교할 수 있습니다 (문자열에서와 같은 모든 문자를 비교하는 것과는 반대로 포인터 비교 만 포함되기 때문에). 동일한 기호의 부동 복사본이 떠 있지 않습니다.
또한 문자열과 달리 기호는 변경할 수 없습니다.
"foo".equal? "foo"
거짓입니까? b) 전역 변수처럼 만드는 기호를 어디에서나 참조 할 수 있습니까?
equal?
Ruby에서 ID 비교를 수행합니다. 와 같은 각 문자열 리터럴 "foo"
은 새 문자열 인스턴스를 만듭니다. Ruby의 문자열은 변경 가능하기 때문에 그렇게 작동합니다. 2. 심볼은 전역 적이지만 전역 변수보다 전역 상수와 비슷합니다. 심볼에는 상태가 없기 때문입니다. 따라서 기호를 사용하는 것이 전역 변수와 같은 방식으로 반 패턴이 아닙니다.
"foo" == "foo"
# => true
답변에 언급 된 것들 중 일부를 보여주기 위해 :
require 'benchmark'
n = 1_000_000
print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo" -> ', ("foo" == "foo" ), "\n"
print ':foo.equal? :foo -> ', (:foo.equal? :foo ), "\n"
print ':foo == :foo -> ', (:foo == :foo ), "\n"
Benchmark.bm(10) do |b|
b.report('string') { n.times { "foo".equal? "foo" }}
b.report('str == str') { n.times { "foo" == "foo" }}
b.report('symbol') { n.times { :foo.equal? :foo }}
b.report('sym == sym') { n.times { :foo == :foo }}
end
실행하면 다음이 출력됩니다.
"foo".equal? "foo" -> false
"foo" == "foo" -> true
:foo.equal? :foo -> true
:foo == :foo -> true
따라서 문자열 equal?
이 내용이 같더라도 다른 객체이므로 문자열을 사용하여 문자열을 비교하는 데 실패합니다. ==
내용을 비교하고 기호와 동등한 검사가 훨씬 빠릅니다.
user system total real
string 0.370000 0.000000 0.370000 ( 0.371700)
str == str 0.330000 0.000000 0.330000 ( 0.326368)
symbol 0.170000 0.000000 0.170000 ( 0.174641)
sym == sym 0.180000 0.000000 0.180000 ( 0.179374)
두 가지 심볼 테스트는 기본적으로 속도와 동일합니다. 1,000,000 회 반복 한 후에는 0.004733 초의 차이 만 있으므로 사용할 때 씻어야한다고 말하고 싶습니다.
==
보다 빠릅니다 .equal?
. 기호 비교는 문자열 비교보다 3 배 이상 빠릅니다.
유명한 책 Agile Web Development with Rails의 인용문이 있는데 ,이 심볼 을 이해하는 데 도움이 될 수 있습니다 .
Rails는 기호를 사용하여 사물을 식별합니다. 특히 메소드 매개 변수의 이름을 지정하고 해시에서 물건을 찾을 때 키로 사용합니다.
redirect_to :action => "edit", :id => params[:id]
기호를 마술처럼 상수로 만드는 문자열 리터럴로 생각할 수 있습니다. 또는 콜론을 "이름이 지정된 것"으로 간주 할 수 있으므로 : id는 "이름이 지정된 것"입니다.
루비에서 각 객체에는 고유 한 객체 식별자 puts "hello".object_id
가 있습니다. irb에 쓰고 두 번 다른 시간 동안 리턴을 누르면 2 개의 다른 리턴 값을 얻게되지만 :hello.object_id
2 번 쓰면 동일한 하나의 리턴 값 만 얻게됩니다. 그 차이점을 설명해야합니다.
이 모든 대답은 하나의 엉뚱한 세부 사항을 생략합니다 .. : foo 기호를 문자열 화하면 얻을 수있는 것입니다. .. 문자열 "foo". 그 후
irb(main):025:0>
irb(main):026:0> :foo
=> :foo
irb(main):027:0> "#{:foo}"
=> "foo"
irb(main):028:0>
irb(main):029:0> 'foo' <=> :foo
=> nil
irb(main):030:0> 'foo' <=> :foo.to_s
=> 0
irb(main):031:0>
따라서 펄 프로그래머에게는 '베어 워드'에 대한 루비의 대답입니다.
Java에 익숙한 경우 Java의 문자열이 변경 불가능하다는 것을 알고있을 수 있습니다. 그런 의미에서 루비의 기호는 비슷합니다. 그것들은 불변입니다. 즉, 특정 심벌의 발생 횟수 :symbol
는 단일 메모리 주소에만 매핑됩니다. 따라서 메모리 사용을 최적화하므로 가능하면 기호를 사용하는 것이 좋습니다.
NSString
. 이 "foo"
항상 동일하게하는 것 "foo"
같다 내부적으로 문자열을 그냥 지적하고 있기 때문에. 그래도 대답은 여전히 혼란 스러울 것입니다.