루비에서 콜론 연산자는 무엇입니까?


234

내가 말할 때 { :bla => 1, :bloop => 2 }정확히 무엇을 :합니까? 문자열과 어떻게 비슷한 지, 어떻게 든 기호에 대해 읽었습니다.

나는 그 개념에 대해 명확하지 않다. 누군가 나를 밝힐 수 있을까?



7
이것을보십시오 : Ruby_Newbie Symbols Guides
Hengjie

이 비디오 는 심볼에 대해 알아야 할 모든 것을 알려줍니다.
totymedli 2016 년

답변:


249

:foo"foo"라는 기호입니다. 기호에는 동일한 이름의 두 기호가 동일하다는 특징이 있습니다.

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

이렇게하면 두 기호를 정말 빠르게 비교할 수 있습니다 (문자열에서와 같은 모든 문자를 비교하는 것과는 반대로 포인터 비교 만 포함되기 때문에). 동일한 기호의 부동 복사본이 떠 있지 않습니다.

또한 문자열과 달리 기호는 변경할 수 없습니다.


2
리터럴 문자열이 문자열 인터 닝을 지원하지 않는 이유가 궁금합니다.
onmyway133

5
@ onmyway133 Ruby의 문자열은 변경 가능하기 때문입니다. 인턴은 불변 값에만 적용됩니다.
Chris Jester-Young

3
a) 왜 "foo".equal? "foo"거짓입니까? b) 전역 변수처럼 만드는 기호를 어디에서나 참조 할 수 있습니까?
Arc676

2
@ Arc676 1. equal?Ruby에서 ID 비교를 수행합니다. 와 같은 각 문자열 리터럴 "foo"은 새 문자열 인스턴스를 만듭니다. Ruby의 문자열은 변경 가능하기 때문에 그렇게 작동합니다. 2. 심볼은 전역 적이지만 전역 변수보다 전역 상수와 비슷합니다. 심볼에는 상태가 없기 때문입니다. 따라서 기호를 사용하는 것이 전역 변수와 같은 방식으로 반 패턴이 아닙니다.
Chris Jester-Young

2
@ Arc676 "foo" == "foo"# => true
Filip Bartuzi

44

답변에 언급 된 것들 중 일부를 보여주기 위해 :

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 배 이상 빠릅니다.
melvynkim

33

기호는 루비로 문자열과 이름을 나타내는 방법입니다.

심볼과 문자열의 주요 차이점은 동일한 이름의 심볼이 초기화되고 루비 세션 동안 메모리에 한 번만 존재한다는 것입니다.

서로 다른 것을 표현하기 위해 같은 단어를 사용해야 할 때 유용합니다


19

유명한 책 Agile Web Development with Rails의 인용문이 있는데 ,이 심볼 을 이해하는 데 도움이 될 수 있습니다 .

Rails는 기호를 사용하여 사물을 식별합니다. 특히 메소드 매개 변수의 이름을 지정하고 해시에서 물건을 찾을 때 키로 사용합니다.

redirect_to :action => "edit", :id => params[:id]

기호를 마술처럼 상수로 만드는 문자열 리터럴로 생각할 수 있습니다. 또는 콜론을 "이름이 지정된 것"으로 간주 할 수 있으므로 : id는 "이름이 지정된 것"입니다.


5

루비에서 각 객체에는 고유 한 객체 식별자 puts "hello".object_id가 있습니다. irb에 쓰고 두 번 다른 시간 동안 리턴을 누르면 2 개의 다른 리턴 값을 얻게되지만 :hello.object_id2 번 쓰면 동일한 하나의 리턴 값 만 얻게됩니다. 그 차이점을 설명해야합니다.


기본적으로 콜론 연산자는 기호
Cesar Jr Rodriguez

2

을 사용 :foo => bar하면 foo가 기호가됩니다. 심볼의 장점은 고유하다는 것입니다. 해시에서 항목을 호출하면 hash[:foo]됩니다.

기호는 문자열보다 적은 메모리를 필요로하므로 프로그램을 좀 더 빠르게 만들고 싶을 때 유용합니다.


0

상징입니다. 기본적으로, 당신은 해시의 두 가지 요소가 키를 가지고 말을 bla하고 bloop당신이 문자열을 사용했다 많은 것처럼, "bla"하고 "bloop". 그러나 문자열보다 적은 메모리를 차지하며 입력하기가 더 쉽습니다.


0

이 모든 대답은 하나의 엉뚱한 세부 사항을 생략합니다 .. : 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>

따라서 펄 프로그래머에게는 '베어 워드'에 대한 루비의 대답입니다.


-1

Java에 익숙한 경우 Java의 문자열이 변경 불가능하다는 것을 알고있을 수 있습니다. 그런 의미에서 루비의 기호는 비슷합니다. 그것들은 불변입니다. 즉, 특정 심벌의 발생 횟수 :symbol는 단일 메모리 주소에만 매핑됩니다. 따라서 메모리 사용을 최적화하므로 가능하면 기호를 사용하는 것이 좋습니다.


1
심볼을 변경할 수 없다는 사실은 애플리케이션 전체에서 심볼이 항상 동일한 인스턴스임을 보장하므로 동일한 객체임을 보장합니다. 다음 참조를 확인하십시오. Troubleshootingers.com/codecorn/ruby/symbols.htm robertsosinski.com/2009/01/11/… 구글이라면 더 많은 정보를 찾을 수 있습니다.
Dhruva Sagar

Java와의 비유에 대해 이야기하고 있습니다. Java 문자열은 기호와 유사하지 않습니다. Java 문자열 리터럴은 모든 문자열이 아닙니다.
smartnut007

아마도 내 진술은 충분히 명확하지 않았다. 그것들은 불변이라는 사실에 대해서만 서로 유사합니다.
Dhruva Sagar

@DhruvaSagar : Objective C를 사용하면 비유가 더 좋습니다 NSString. 이 "foo"항상 동일하게하는 것 "foo"같다 내부적으로 문자열을 그냥 지적하고 있기 때문에. 그래도 대답은 여전히 ​​혼란 스러울 것입니다.
Rafael Bugajewski
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.