วิธีทำความเข้าใจสัญลักษณ์ใน Ruby


85

แม้จะอ่าน "การทำความเข้าใจสัญลักษณ์ทับทิม " แต่ฉันก็ยังสับสนกับการแสดงข้อมูลในหน่วยความจำเมื่อต้องใช้สัญลักษณ์ หากสัญลักษณ์สองสัญลักษณ์ที่อยู่ในวัตถุต่างกันมีอยู่ในตำแหน่งหน่วยความจำเดียวกันแล้วสัญลักษณ์นั้นมีค่าต่างกันอย่างไร? ฉันคาดว่าตำแหน่งหน่วยความจำเดียวกันจะมีค่าเดียวกัน

นี่เป็นคำพูดจากลิงค์:

ซึ่งแตกต่างจากสตริงสัญลักษณ์ที่มีชื่อเดียวกันจะเริ่มต้นและมีอยู่ในหน่วยความจำเพียงครั้งเดียวในระหว่างเซสชันของทับทิม

ฉันไม่เข้าใจวิธีจัดการเพื่อแยกความแตกต่างของค่าที่อยู่ในตำแหน่งหน่วยความจำเดียวกัน

ลองพิจารณาตัวอย่างนี้:

patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }

patient1.each_key {|key| puts key.object_id.to_s}
3918094
patient2.each_key {|key| puts key.object_id.to_s}
3918094

patient1และpatient2เป็นแฮชทั้งคู่ก็ใช้ได้ :rubyอย่างไรก็ตามเป็นสัญลักษณ์ หากเราจะแสดงผลลัพธ์ต่อไปนี้:

patient1.each_key {|key| puts key.to_s}

แล้วจะเอาท์พุทอะไร? "red", หรือ"programming"?

เมื่อลืมแฮชไปสักวินาทีฉันคิดว่าสัญลักษณ์เป็นตัวชี้ค่า คำถามที่ฉันมีคือ:

  • ฉันสามารถกำหนดค่าให้กับสัญลักษณ์ได้หรือไม่?
  • สัญลักษณ์เป็นเพียงตัวชี้ไปยังตัวแปรที่มีค่าอยู่หรือไม่?
  • หากสัญลักษณ์เป็นสากลหมายความว่าสัญลักษณ์ชี้ไปที่สิ่งหนึ่งเสมอหรือไม่?

1
มันจะแสดงผล ": ruby" เนื่องจากคุณกำลังพิมพ์ Symbol ถ้าคุณบอกว่าputs patient1[:ruby]มันจะพิมพ์ "สีแดง" ถ้าคุณบอกว่าputs patient2[:ruby]มันจะพิมพ์
ROSS

1
สัญลักษณ์ไม่ได้เป็นตัวชี้ค่า สัญลักษณ์ภายในเป็นเพียงจำนวนเต็ม
akuhn

คำตอบ:


62

พิจารณาสิ่งนี้:

x = :sym
y = :sym
(x.__id__ == y.__id__ ) && ( :sym.__id__ == x.__id__) # => true

x = "string"
y = "string"
(x.__id__ == y.__id__ ) || ( "string".__id__ == x.__id__) # => false

อย่างไรก็ตามคุณสร้างวัตถุสัญลักษณ์ตราบใดที่เนื้อหาเหมือนกันมันจะอ้างถึงวัตถุเดียวกันในหน่วยความจำ นี้ไม่ได้เป็นปัญหาเพราะสัญลักษณ์เป็นวัตถุที่ไม่เปลี่ยนรูป สตริงไม่แน่นอน


(ตอบกลับความคิดเห็นด้านล่าง)

ในบทความต้นฉบับค่าจะไม่ถูกเก็บไว้ในสัญลักษณ์ แต่จะถูกเก็บไว้ในแฮช พิจารณาสิ่งนี้:

hash1 = { "string" => "value"}
hash2 = { "string" => "value"}

สิ่งนี้สร้างวัตถุหกชิ้นในหน่วยความจำ - วัตถุสตริงสี่ชิ้นและวัตถุแฮชสองชิ้น

hash1 = { :symbol => "value"}
hash2 = { :symbol => "value"}

สิ่งนี้จะสร้างวัตถุห้าชิ้นในหน่วยความจำเท่านั้น - หนึ่งสัญลักษณ์สองสายและสองวัตถุแฮช


อย่างไรก็ตามตัวอย่างในลิงก์แสดงสัญลักษณ์ที่มีค่าต่างกันแต่สัญลักษณ์มีชื่อเดียวกันและตำแหน่งหน่วยความจำเดียวกัน เมื่อเอาท์พุทมีค่าต่างกันนั่นคือส่วนที่ฉันไม่ได้รับ แน่นอนว่าควรมีค่าเท่ากัน?
Kezzer

1
ฉันเพิ่งทำการแก้ไขเพื่อพยายามอธิบายว่าฉันยังสับสนอยู่ สมองของฉันไม่สามารถคำนวณได้)
Kezzer

48
สัญลักษณ์ไม่มีค่า แต่เป็นค่า แฮชมีค่า
Mladen Jablanović

6
เป็นHash(สร้างโดย {... => ... } ในโค้ดของคุณ) ที่เก็บคู่คีย์ / ค่าไม่ใช่คู่Symbolของตัวเอง Symbols (เช่น:symbolหรือ:symหรือ:ruby) เป็นกุญแจในคู่ที่ Hashพวกเขา "ชี้" ไปที่สิ่งใดเป็นส่วนหนึ่งเท่านั้น
James A. Rosen

1
สัญลักษณ์นี้ถูกใช้เป็นคีย์ในแฮชไม่ใช่ค่านั่นคือสาเหตุที่ทำให้แตกต่างกันได้คล้ายกับการใช้คำว่า key1 = 'ruby' และ hash1 = {key1 => 'value' ... } hash2 = { key1 => 'value2' ... }
Joshua Olson

53

ฉันสามารถคลำสัญลักษณ์ได้เมื่อคิดแบบนี้ สตริง Ruby เป็นวัตถุที่มีวิธีการและคุณสมบัติมากมาย ผู้คนชอบใช้สตริงสำหรับคีย์และเมื่อใช้สตริงสำหรับคีย์ก็จะไม่ใช้วิธีการพิเศษเหล่านั้นทั้งหมด ดังนั้นพวกเขาจึงสร้างสัญลักษณ์ซึ่งเป็นสตริงออบเจ็กต์ที่มีการลบฟังก์ชันทั้งหมดออกยกเว้นสิ่งที่จำเป็นเพื่อให้เป็นคีย์ที่ดี

เพียงแค่คิดว่าสัญลักษณ์เป็นสตริงคงที่


3
อ่านกระทู้นี้น่าจะเข้าท่าที่สุดสำหรับฉัน : ทับทิมถูกเก็บไว้ที่ใดที่หนึ่งในหน่วยความจำถ้าฉันใช้ "ทับทิม" ที่ไหนสักแห่งจากนั้น "ทับทิม" ที่อื่นอีกครั้งมันเป็นเพียงการทำซ้ำ ดังนั้นการใช้สัญลักษณ์จึงเป็นวิธีลดความซ้ำซ้อนของข้อมูลทั่วไป อย่างที่คุณพูดสตริงคงที่ ฉันเดาว่ามีกลไกพื้นฐานบางอย่างที่จะพบสัญลักษณ์นั้นอีกครั้งเพื่อใช้?
Kezzer

1
@Kezzer คำตอบนี้ดีมากและดูเหมือนจะใช่สำหรับฉัน แต่ความคิดเห็นของคุณบอกว่ามีบางอย่างที่แตกต่างออกไปและไม่ถูกต้องหรือทำให้เข้าใจผิดความคิดเห็นของคุณพูดถึงการทำซ้ำข้อมูลด้วยสตริงและนั่นเป็นสาเหตุของสัญลักษณ์ที่ผิดหรือทำให้เข้าใจผิดใช่การใช้ สัญลักษณ์หลาย ๆ ครั้งจะไม่ใช้พื้นที่หน่วยความจำเพิ่มขึ้น แต่คุณสามารถมีได้สำหรับสตริงในหลายภาษาเช่นภาษาโปรแกรมบางภาษาหากคุณเขียน "abc" และที่อื่น "abc" คอมไพเลอร์จะเห็นว่าเป็นสตริงค่าเดียวกันและเก็บไว้ ในที่เดียวกันทำให้เป็นวัตถุเดียวกันซึ่งเรียกว่า string interning และ c # ทำเช่นนั้น
barlop

ดังนั้นมันจึงเป็นสตริงที่มีน้ำหนักเบาอย่างไม่น่าเชื่อ?
stevec

34

สัญลักษณ์:rubyนี้ไม่มี"red"หรือ"programming". สัญลักษณ์เป็นเพียงสัญลักษณ์:ruby :rubyมันคือแฮชของคุณpatient1และpatient2แต่ละค่าจะมีค่าเหล่านั้นในแต่ละกรณีจะชี้ไปที่คีย์เดียวกัน

ลองคิดดู: ถ้าคุณเข้าไปในห้องนั่งเล่นในเช้าวันคริสต์มาสและเห็นกล่องสองกล่องที่มีป้ายกำกับว่า "Kezzer" อยู่ ออนมีถุงเท้าอยู่ข้างในและอีกอันมีถ่านหิน คุณจะไม่สับสนและถามว่า "Kezzer" มีทั้งถุงเท้าและถ่านหินได้อย่างไรแม้ว่าจะเป็นชื่อเดียวกันก็ตาม เนื่องจากชื่อไม่ได้มีของขวัญ (เส็งเคร็ง) มันแค่ชี้ไปที่พวกเขา ในทำนองเดียวกัน:rubyไม่มีค่าในแฮชของคุณเพียงแค่ชี้ไปที่ค่าเหล่านั้น


2
คำตอบนี้สมเหตุสมผล
Vass

สิ่งนี้ดูเหมือนเป็นการผสมผสานแฮชและสัญลักษณ์ทั้งหมด สัญลักษณ์ไม่ได้ชี้ไปที่ค่าหากคุณต้องการบอกว่ามันทำเมื่ออยู่ในแฮชนั่นอาจจะเป็นที่ถกเถียงกันอยู่ แต่สัญลักษณ์ไม่จำเป็นต้องอยู่ในแฮช คุณสามารถพูดได้ว่าmystring = :steveT สัญลักษณ์ไม่ชี้ไปที่อะไรเลย คีย์ในแฮชมีค่าที่เกี่ยวข้องและคีย์อาจเป็นสัญลักษณ์ แต่สัญลักษณ์ไม่จำเป็นต้องอยู่ในแฮช
barlop

27

คุณอาจสันนิษฐานว่าการประกาศที่คุณได้กำหนดให้ค่าของ Symbol เป็นสิ่งอื่นที่ไม่ใช่สิ่งที่เป็นอยู่ ในความเป็นจริง Symbol เป็นเพียงค่า String "internalized" ที่คงที่ เป็นเพราะมีการจัดเก็บโดยใช้ตัวระบุจำนวนเต็มอย่างง่ายซึ่งมักใช้เนื่องจากมีประสิทธิภาพมากกว่าการจัดการสตริงที่มีความยาวผันแปรจำนวนมาก

ใช้กรณีตัวอย่างของคุณ:

patient1 = { :ruby => "red" }

ควรอ่านว่า: "ประกาศตัวแปร patient1 และกำหนดให้เป็น Hash และในนี้จะเก็บค่า" สีแดง "ไว้ใต้คีย์ (สัญลักษณ์ 'ทับทิม')"

อีกวิธีหนึ่งในการเขียนสิ่งนี้คือ:

patient1 = Hash.new
patient1[:ruby] = 'red'

puts patient1[:ruby]
# 'red'

ในขณะที่คุณทำการมอบหมายงานแทบจะไม่น่าแปลกใจเลยที่ผลลัพธ์ที่คุณได้รับกลับมาจะเหมือนกับสิ่งที่คุณได้รับมอบหมายในตอนแรก

แนวคิด Symbol อาจทำให้สับสนเล็กน้อยเนื่องจากไม่ใช่คุณลักษณะของภาษาอื่น ๆ ส่วนใหญ่

อ็อบเจ็กต์ String แต่ละตัวมีความแตกต่างกันแม้ว่าค่าจะเหมือนกัน:

[ "foo", "foo", "foo", "bar", "bar", "bar" ].each do |v|
  puts v.inspect + ' ' + v.object_id.to_s
end

# "foo" 2148099960
# "foo" 2148099940
# "foo" 2148099920
# "bar" 2148099900
# "bar" 2148099880
# "bar" 2148099860

ทุกสัญลักษณ์ที่มีค่าเดียวกันหมายถึงวัตถุเดียวกัน:

[ :foo, :foo, :foo, :bar, :bar, :bar ].each do |v|
  puts v.inspect + ' ' + v.object_id.to_s
end

# :foo 228508
# :foo 228508
# :foo 228508
# :bar 228668
# :bar 228668
# :bar 228668

การแปลงสตริงเป็นสัญลักษณ์จะแมปค่าที่เหมือนกันกับสัญลักษณ์เฉพาะเดียวกัน:

[ "foo", "foo", "foo", "bar", "bar", "bar" ].each do |v|
  v = v.to_sym
  puts v.inspect + ' ' + v.object_id.to_s
end

# :foo 228508
# :foo 228508
# :foo 228508
# :bar 228668
# :bar 228668
# :bar 228668

ในทำนองเดียวกันการแปลงจาก Symbol เป็น String จะสร้างสตริงที่แตกต่างกันทุกครั้ง:

[ :foo, :foo, :foo, :bar, :bar, :bar ].each do |v|
  v = v.to_s
  puts v.inspect + ' ' + v.object_id.to_s
end

# "foo" 2148097820
# "foo" 2148097700
# "foo" 2148097580
# "bar" 2148097460
# "bar" 2148097340
# "bar" 2148097220

คุณสามารถคิดว่าค่า Symbol ถูกดึงมาจากตาราง Hash ภายในและคุณสามารถดูค่าทั้งหมดที่เข้ารหัสเป็น Symbols ได้โดยใช้วิธีการเรียกง่ายๆ:

Symbol.all_values

# => [:RUBY_PATCHLEVEL, :vi_editing_mode, :Separator, :TkLSHFT, :one?, :setuid?, :auto_indent_mode, :setregid, :back, :Fail, :RET, :member?, :TkOp, :AP_NAME, :readbyte, :suspend_context, :oct, :store, :WNOHANG, :@seek, :autoload, :rest, :IN_INPUT, :close_read, :type, :filename_quote_characters=, ...

เมื่อคุณกำหนดสัญลักษณ์ใหม่โดยสัญกรณ์โคลอนหรือโดยใช้. to_sym ตารางนี้จะโตขึ้น


18

สัญลักษณ์ไม่ใช่ตัวชี้ ไม่มีค่า สัญลักษณ์เพียงแค่มี :rubyคือสัญลักษณ์:rubyและนั่นคือทั้งหมดที่มี มันไม่ได้มีค่าก็ไม่ได้ทำ:rubyอะไรมันก็มีอยู่เป็นสัญลักษณ์ สัญลักษณ์:rubyคือค่าเช่นเดียวกับตัวเลข 1 ไม่ชี้ไปที่ค่าอื่นใดที่มากกว่าตัวเลข 1


13
patient1.each_key {|key| puts key.to_s}

แล้วจะเอาท์พุทอะไร? "สีแดง" หรือ "การเขียนโปรแกรม"?

ไม่ว่าจะเป็น "ทับทิม"

คุณสับสนสัญลักษณ์และแฮช ไม่เกี่ยวข้องกัน แต่มีประโยชน์ร่วมกัน สัญลักษณ์ในคำถามคือ:ruby; ไม่มีส่วนเกี่ยวข้องกับค่าในแฮชและการแสดงจำนวนเต็มภายในจะเหมือนกันเสมอและ "ค่า" (เมื่อแปลงเป็นสตริง) จะเป็น "ทับทิม" เสมอ


11

ในระยะสั้น

สัญลักษณ์ช่วยแก้ปัญหาในการสร้างการแสดงที่มนุษย์อ่านได้และไม่เปลี่ยนรูปซึ่งยังมีข้อดีของการที่รันไทม์ค้นหาได้ง่ายกว่าสตริง คิดว่ามันเหมือนชื่อหรือฉลากที่สามารถใช้ซ้ำได้

เหตุผล: สีแดงดีกว่า "สีแดง"

ในภาษาเชิงวัตถุแบบไดนามิกคุณจะสร้างโครงสร้างข้อมูลที่ซ้อนกันซับซ้อนพร้อมการอ้างอิงที่อ่านได้ กัญชาเป็นกรณีการใช้งานทั่วไปที่คุณแมค่าคีย์ไม่ซ้ำกัน - ที่ไม่ซ้ำกันที่อย่างน้อยจะได้เช่นกัน คุณไม่สามารถมีคีย์ "สีแดง" ได้มากกว่าหนึ่งคีย์ต่อแฮช

อย่างไรก็ตามการใช้ดัชนีตัวเลขแทนคีย์สตริงจะมีประสิทธิภาพมากกว่า ดังนั้นสัญลักษณ์จึงถูกนำมาใช้เพื่อประนีประนอมระหว่างความเร็วและความสามารถในการอ่าน สัญลักษณ์แก้ไขได้ง่ายกว่าสตริงที่เทียบเท่ากันมาก การที่มนุษย์สามารถอ่านได้และง่ายสำหรับรันไทม์ในการแก้ไขสัญลักษณ์จึงเป็นส่วนเสริมที่เหมาะสำหรับภาษาแบบไดนามิก

สิทธิประโยชน์

เนื่องจากสัญลักษณ์ไม่เปลี่ยนรูปจึงสามารถใช้ร่วมกันระหว่างรันไทม์ได้ หากอินสแตนซ์แฮชสองอินสแตนซ์มีความต้องการคำศัพท์หรือความหมายทั่วไปสำหรับรายการสีแดงสัญลักษณ์: สีแดงจะใช้หน่วยความจำประมาณครึ่งหนึ่งที่สตริง "สีแดง" จะต้องมีสำหรับแฮชสองตัว

เนื่องจาก: สีแดงจะแก้ไขกลับไปยังตำแหน่งเดิมในหน่วยความจำเสมอจึงสามารถนำกลับมาใช้ซ้ำได้ในหลายร้อยอินสแตนซ์โดยแทบจะไม่เพิ่มหน่วยความจำในขณะที่การใช้ "สีแดง" จะเพิ่มต้นทุนหน่วยความจำเนื่องจากแต่ละอินสแตนซ์แฮชจะต้องจัดเก็บสตริงที่เปลี่ยนแปลงได้ การสร้าง

ไม่แน่ใจว่า Ruby ใช้สัญลักษณ์ / สตริงอย่างไร แต่เห็นได้ชัดว่าสัญลักษณ์มีค่าใช้จ่ายในการใช้งานน้อยกว่าในรันไทม์เนื่องจากเป็นการแสดงแบบคงที่ สัญลักษณ์บวกใช้อักขระน้อยกว่าหนึ่งอักขระในการพิมพ์กว่าสตริงที่ยกมาและการพิมพ์น้อยลงเป็นการแสวงหารูบี้ลิสต์ที่แท้จริงตลอดไป

สรุป

ด้วยสัญลักษณ์เช่น: สีแดงคุณจะสามารถอ่านการแสดงสตริงได้โดยมีค่าใช้จ่ายน้อยลงเนื่องจากต้นทุนในการดำเนินการเปรียบเทียบสตริงและความจำเป็นในการจัดเก็บอินสแตนซ์สตริงแต่ละรายการในหน่วยความจำ


4

ฉันอยากจะแนะนำให้อ่านบทความ Wikipedia เกี่ยวกับตารางแฮช - ฉันคิดว่ามันจะช่วยให้คุณเข้าใจ{:ruby => "red"}ถึงความหมายจริงๆ

การออกกำลังกายที่จะช่วยให้ความเข้าใจของสถานการณ์อื่น: {1 => "red"}พิจารณา ตามความหมายนี่ไม่ได้หมายความว่า "ตั้งค่า1เป็น"red"" ซึ่งเป็นไปไม่ได้ใน Ruby แต่ก็หมายความว่า "สร้างแฮวัตถุและเก็บค่าสำหรับคีย์"red"1


3
patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }

patient1.each_key {|key| puts key.object_id.to_s}
3918094
patient2.each_key {|key| puts key.object_id.to_s}
3918094

patient1และpatient2เป็นแฮชทั้งคู่ก็ใช้ได้ :rubyอย่างไรก็ตามเป็นสัญลักษณ์ หากเราจะแสดงผลลัพธ์ต่อไปนี้:

patient1.each_key {|key| puts key.to_s}

แล้วจะเอาท์พุทอะไร? "สีแดง" หรือ "การเขียนโปรแกรม"?

ไม่แน่นอน rubyการส่งออกจะเป็น ซึ่ง BTW คุณสามารถค้นพบได้ในเวลาน้อยกว่าที่คุณใช้ในการพิมพ์คำถามโดยพิมพ์ลงใน IRB แทน

ทำไมจะว่าจะเป็นredหรือprogramming? สัญลักษณ์มักจะประเมินตัวเองเสมอ ค่าของสัญลักษณ์ที่:rubyเป็นสัญลักษณ์:rubyของตัวเองและเป็นตัวแทนสตริงของสัญลักษณ์เป็นค่าสตริง:ruby"ruby"

[BTW: putsแปลงอาร์กิวเมนต์เป็นสตริงเสมออย่างไรก็ตาม ไม่จำเป็นต้องเรียกto_sมัน]


ฉันไม่มี IRB ในเครื่องปัจจุบันและฉันจะไม่สามารถติดตั้งได้ด้วยเหตุนี้ฉันจึงขอโทษด้วย
Kezzer

2
@ Kezzer: ไม่ต้องกังวลฉันแค่อยากรู้อยากเห็น บางครั้งคุณฝังตัวเองลงไปในปัญหาจนมองไม่เห็นสิ่งที่ง่ายที่สุดอีกต่อไป เมื่อฉันตัดและวางคำถามของคุณลงใน IRB โดยพื้นฐานแล้วฉันแค่สงสัยว่า: "ทำไมเขาไม่ทำด้วยตัวเอง" และไม่ต้องกังวลคุณไม่ใช่คนแรก (หรือจะเป็นคนสุดท้าย) ที่ถามว่า "พิมพ์อะไร" เมื่อคำตอบคือ "แค่รัน!" BTW: นี่คือ IRB ทันทีของคุณทุกที่ทุกเวลาไม่จำเป็นต้องติดตั้ง: TryRuby.OrgหรือRuby-Versions.Netให้คุณเข้าถึง SSH ใน MRI ทุกเวอร์ชันที่เคยเปิดตัว + YARV + JRuby + Rubinius + REE
Jörg W Mittag

ขอบคุณแค่ลองเล่นดูตอนนี้ ฉันยังคงสับสนเล็กน้อยแม้ว่าจะต้องทบทวนอีกครั้ง
Kezzer

1

ฉันยังใหม่กับ Ruby แต่ฉันคิดว่า (หวังว่า?) นี่เป็นวิธีง่ายๆในการดู ...

สัญลักษณ์ไม่ใช่ตัวแปรหรือค่าคงที่ มันไม่ได้อยู่ในหรือชี้ไปที่ค่า สัญลักษณ์คือค่า

ทั้งหมดคือสตริงที่ไม่มีวัตถุอยู่เหนือศีรษะ ข้อความและเฉพาะข้อความ

ดังนั้นสิ่งนี้:

"hellobuddy"

เหมือนกับสิ่งนี้:

:hellobuddy

ยกเว้นคุณไม่สามารถทำได้ตัวอย่างเช่น hellobuddy.upcase เป็นค่าสตริงและเป็นค่าสตริงเท่านั้น

ในทำนองเดียวกันสิ่งนี้:

greeting =>"hellobuddy"

เหมือนกับสิ่งนี้:

greeting => :hellobuddy

แต่อีกครั้งโดยไม่มีวัตถุสตริงเหนือศีรษะ


-1

วิธีง่ายๆอย่างหนึ่งในการคาดเดาสิ่งนี้คือการคิดว่า "ถ้าฉันใช้สตริงแทนที่จะเป็นสัญลักษณ์ล่ะ?

patient1 = { "ruby" => "red" }
patient2 = { "ruby" => "programming" }

มันไม่สับสนเลยใช่มั้ย? คุณกำลังใช้ "ทับทิม" เป็นสำคัญในกัญชา

"ruby"เป็นสตริงลิเทอรัลนั่นคือค่า คุณไม่สามารถใช้ที่อยู่หน่วยความจำหรือตัวชี้ได้ เวลาที่คุณเรียกทุกคน"ruby"คุณจะสร้างตัวอย่างใหม่ของมันนั่นคือการสร้างเซลล์หน่วยความจำใหม่ที่มีมูลค่าเท่ากัน "ruby"-

กัญชาแล้วไป "มีอะไรค่าคีย์ของฉันได้อย่างไรโอ้มัน"ruby". แล้วแมค่าที่จะ 'สีแดง' หรือ 'การเขียนโปรแกรม'. ในคำอื่น ๆ:rubyไม่ dereference ไป"red"หรือ"programming". กัญชาแผนที่ :rubyไปหรือ"red""programming"

เปรียบเทียบว่าถ้าเราใช้สัญลักษณ์

patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }

คุณค่าของ:rubyยัง"ruby"มีประสิทธิภาพ

ทำไม? เพราะสัญลักษณ์เป็นหลักคงที่สตริง ค่าคงที่ไม่มีหลายอินสแตนซ์ ที่อยู่หน่วยความจำเดียวกัน และที่อยู่หน่วยความจำมีค่าหนึ่งเมื่อถูกอ้างถึง สำหรับสัญลักษณ์ชื่อตัวชี้คือสัญลักษณ์และค่าที่ถูกอ้างถึงคือสตริงซึ่งตรงกับชื่อสัญลักษณ์ในกรณี"ruby"นี้

เมื่ออยู่ในแฮชคุณไม่ได้ใช้สัญลักษณ์ตัวชี้ แต่เป็นค่าที่อ้างอิง คุณไม่ได้ใช้:rubyแต่"ruby". จากนั้นแฮชจะค้นหาคีย์"ruby"ค่าคือ"red"หรือ"programming"ขึ้นอยู่กับว่าคุณกำหนดแฮชอย่างไร

การเปลี่ยนกระบวนทัศน์และแนวคิดแบบนำกลับบ้านคือค่าของสัญลักษณ์เป็นแนวคิดที่แยกจากกันโดยสิ้นเชิงจากค่าที่แฮชซึ่งกำหนดให้เป็นกุญแจสำคัญของแฮชนั้น


1
อะไรคือความเข้าใจผิดหรือข้อผิดพลาดในคำอธิบายนี้ผู้ลงคะแนน? อยากรู้อยากเห็นเพื่อการเรียนรู้
ahnbizcad

เพียงเพราะการเปรียบเทียบอาจทำให้บางคนไม่พอใจไม่ได้หมายความว่าจะมีข้อบกพร่อง
ahnbizcad

3
ฉันไม่เห็นข้อผิดพลาดใด ๆ จำเป็น แต่เป็นการยากมากที่จะระบุสิ่งที่คุณพยายามจะพูดในคำตอบนี้
Reverse Engineered

x ถูกตีความและกำหนดแนวความคิดแตกต่างกันไปตามบริบท / เอนทิตีที่ทำการตีความ ค่อนข้างเรียบง่าย
ahnbizcad

1
ยกเครื่องคำตอบ ขอบคุณสำหรับความคิดเห็น.
ahnbizcad
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.