詳細検索

저는 루비의 혼란스러운 배열, 해시, 심볼을 요약하려고 했습니다.

아바타
글쓴이 maeno
5분 읽기

저는 루비의 혼란스러운 배열, 해시, 심볼을 요약하려고 했습니다.
日本語에서 번역 • 원문 보기

새해 복 많이 받으세요.

음, 2015년에 첫 글을 지금 가장 뜨거운 루비 이야기로 시작하려고 해요.

기본적인 요약부터 시작하자면, Ruby에는 두 가지 유형의 배열이 있습니다: 1차원 배열인 'array' 클래스 객체와 다차원 배열(연관 배열)인 '해시' 클래스 객체입니다. 각 배열 객체는 정의 시 요소를 감싸는 문자 그대로의 기호로 구분됩니다:

array = ["A", "B", "C"] # 배열 변수 배열 정의
hash1 = {:first=> "A", :second=> "B", :third = > "C"} # 해시 해시1을 정의하세요

'array' 클래스 객체는 1차원 배열로, 각 요소 값에 자동으로 숫자 첨자를 할당하여 각 요소를 숫자 첨자 인덱스로 접근할 수 있게 합니다.

array = ["A", "B", "C"]
Places array[0] # "A"가 표시됩니다

반면, '해시' 클래스 객체는 키-값 객체이므로 문자열 타입 첨자(키)로 원자 값을 접근할 수 있습니다.

hash2 = {"first" => "A", "second" => "B", "third" => "C"}
해시2["first"] # "A"가 표시됩니다

여기 첫 번째 예시에서 정의된 해시1과 해시2가 키를 다르게 지정한 것을 눈치채셨나요? 해시1과 해시2는 같은 요소 값을 가지지만, 키가 다르기 때문에 같은 해시가 아닙니다.

해시1 넣음 == 해시2 # false

Hash1은 해시 키가 기호인 해시이고, Hash2는 키가 문자열인 해시이므로 각각 다른 해시입니다. 해시 키는 기호든 문자열이든 해시 내에서 고유해야 합니다. 또한, 문자열 키와 같은 이름의 기호를 섞으면 각 요소가 다른 것으로 취급됩니다.

hash3 = {:element => "A", :element => "B"}
hash4 = {"element" => "A", "element" => "B", :element => "A"}
해시3 # {:element=>"B"}를 삽입합니다
hash4 # {"element"=>"B", :element=>"A"}를 넣습니다

해시 키를 기호로 사용하면 할당 표현식을 줄일 수 있습니다.

hash5 = {:first => "A", :second => "B"}
hash6 = {첫 번째: "A", 두 번째: "B"}
해시5 == 해시6 # 참

hash6 작성 방법은 JavaScript와 CSS 표현식에 익숙하므로, 코딩한 사람들에게는 사용하기 쉬울 수 있습니다. 심볼릭 해시의 요소 값을 얻으려면 다음을 수행하세요:

hash5[:first] # "A"
Hash6[:second] #를 넣으면 "B"가 표시됩니다

처음 루비 코드를 봤을 때, 해시 리터럴(접두사 ":" 문자)이 기호 해시 할당 표현식이 앞이나 뒤에 붙는다는 점을 이해하지 못해 꽤 혼란스러웠습니다. 그래서 저는 익숙한 PHP 해시를 사용했는데, 그게 가장 이해하기 쉬웠습니다.

하지만 **해시는 심볼을 사용할 때 더 빠르게 실행됩니다. **

따라서 기호를 사용할 수 있다면 해시 키를 기호로 사용하는 것이 더 낫습니다. 그렇다면 해시를 생성하고 싶다면 왜 모든 곳에서 기호의 키를 사용하지 않겠습니까? ──그렇게 생각할 수도 있습니다. 하지만 기호 이름에 사용할 수 없는 문자들도 있습니다. 대표적인 예로는 "-(하이픈)"이 있습니다.

hash7={:first-element=> "A"}} # 이로 인해 오류가 발생합니다
hash8 = {:"first-element" => "A"}} # ""를 포함하는 전체 문자열이 기호입니다.
해시9 = {:first_element => "A", :secondElement => "B", :secondelement => 2}
hash9 # {:first_element=>"A", :secondElement=>"B", :secondelement=>2}

반폭 영숫자 숫자에 "_ (밑줄)" 기호를 붙여 문자로 사용할 수 있는 문자를 인식하면 충분합니다. 반너비 알파벳의 대문자와 소문자는 구별되며, 반문자 숫자는 기호 이름의 첫 글자로 사용할 수 없습니다.

하지만 사용할 수 없는 문자가 있더라도, 해시 키에 문자열 키를 사용하는 것은 최대한 피하는 것이 좋습니다. 이는 심볼이 고유한 객체이기 때문에, 외부에서 파괴적 메서드를 사용해도 그 고유성을 유지할 수 있기 때문입니다. 즉, 해시의 키 정보는 어떤 상황에서도 변하지 않기 때문에, 애플리케이션 안팎에서 해시 구조의 규칙성을 유지하는 장점이 있습니다(사실, 이는 단지 형이상학적 이점일 뿐입니다...).

예를 들어, 해시 키만 제거하고 파괴적 방법으로 처리하는 것이 어떤 느낌일지 상상해 봅시다...

hash10 = {"element" => "A", :element => "B"}
1..3의 I
  hash10.keys.each do |key|
    key.upcase.object_id
  끝
끝
------ 
22462512 # 문자열 키 "요소"의 객체 ID (for loop 1st)
217508 # 심볼 키: 원소의 객체 ID (루프 1에 대해 )
22460736 # 문자열 키 "요소"의 객체 ID (루프 2번째 기준)
217508 # 심볼 키: 원소의 객체 ID (for loop 2nd)
22460484 # 문자열 키 "element"의 객체 ID (for loop 3rd)
217508 # 심볼 키: 원소의 객체 ID (for loop 3rd)

이는 '업케이스' 메서드로 해시 키를 세 번 대문자로 변환하기 위한 것입니다. 모든 확장된 해시 키(변수 키 값)는 'ELEMENT'로 변환되지만, 문자열 키의 경우 '업케이스' 메서드가 호출될 때마다 객체 ID가 변경됩니다. 즉, 시스템 내부에서는 다른 객체로 인식됩니다. 반면, 심볼 키의 경우, '업케이스' 메서드가 몇 번 호출되든 객체 ID는 변하지 않습니다. 즉, 시스템 내 기호 ':element'는 고유하게 유지됩니다.

기호를 쉽게 표현하고 싶다면 "전역 변수 문자열 상수 객체"라고 할 수 있겠네요? (반대로, 이해하기 어려울 수도 있습니다...)

──어쨌든, 루비 해시를 다루기 전에 기호를 이해하는 게 더 낫다고 생각했어요.

Related Articles