สัญลักษณ์มีลักษณะดังนี้:
:testing
บางคนสับสนสัญลักษณ์กับตัวแปรแต่ไม่เกี่ยวอะไรกับตัวแปร…
…สัญลักษณ์เป็นเหมือนสตริงมากกว่ามาก .
สัญลักษณ์และสตริง Ruby ต่างกันอย่างไร
สตริงใช้เพื่อทำงานกับ ข้อมูล .
สัญลักษณ์คือตัวระบุ .
นั่นคือความแตกต่างหลัก:
สัญลักษณ์ไม่ใช่แค่สตริงประเภทอื่น แต่มีจุดประสงค์ที่แตกต่างกัน
เมื่อใดควรใช้สัญลักษณ์
การใช้สัญลักษณ์ทั่วไปอย่างหนึ่งคือ แสดงชื่อตัวแปรของเมธอดและอินสแตนซ์ .
ตัวอย่าง :
attr_reader :title
:title
หลัง attr_reader เป็นสัญลักษณ์แทน @title
ตัวแปรอินสแตนซ์
คุณยังใช้สัญลักษณ์เป็นแฮชคีย์ได้อีกด้วย
ตัวอย่าง :
hash = {a: 1, b: 2, c: 3}
ประโยชน์?
สัญลักษณ์ดูดีกว่า พวกมันเปลี่ยนไม่ได้ &หากคุณเปรียบเทียบคีย์สตริงกับคีย์สัญลักษณ์ คุณจะพบว่าคีย์สตริงช้าลงประมาณ 1.70 เท่า
โดยที่ไม่เปลี่ยนรูป ฉันหมายความว่า ทุกสัญลักษณ์มีเอกลักษณ์ และไม่สามารถเปลี่ยนแปลงได้:
:rubyguides.object_id # 437768 :rubyguides.object_id # 437768
สัญลักษณ์ทั้งสองนี้เป็นวัตถุเดียวกัน เพราะมีรหัสวัตถุเหมือนกัน
สามารถใช้สัญลักษณ์ในเมตาโปรแกรมมิงเช่น send
:
[1,2,3].send(:first)
โดยสรุป :
คุณควรใช้สัญลักษณ์เป็นชื่อ หรือป้ายกำกับสำหรับสิ่งต่าง ๆ (เช่นวิธีการ) และใช้สตริงเมื่อคุณสนใจ ข้อมูล . มากขึ้น (ตัวอักษรแต่ละตัว)
การแปลงระหว่างสตริงและสัญลักษณ์
คุณสามารถแปลงสัญลักษณ์เป็นสตริงได้เมื่อจำเป็น
ทำไมคุณถึงอยากทำอย่างนั้น
เนื่องจากสัญลักษณ์มีเพียงชุดย่อยของเมธอดที่มีสตริงเท่านั้น
และสัญลักษณ์ไม่สามารถเปลี่ยนแปลงได้ ดังนั้นหากคุณต้องการทำงานกับอักขระแต่ละตัวของสัญลักษณ์ คุณต้องการสตริง
คุณสามารถทำได้โดยใช้ to_s
วิธีการ
ตัวอย่างเช่น เมื่อใช้ method_missing
คุณได้รับชื่อของวิธีการที่ขาดหายไปเป็นสัญลักษณ์ คุณอาจต้องการตรวจสอบว่าชื่อเมธอดนี้ตรงกับรูปแบบเฉพาะหรือไม่ (เช่น ลงท้ายด้วย ?
)
ตัวอย่าง :
def method_missing(method_name, *args, &block) if method_name.to_s[-1] == "?" # do something else super end end
คุณยังสามารถแปลงวัตถุสตริงเป็นวัตถุสัญลักษณ์ได้
วิธีการคือ String#to_sym
:
"rubyguides".to_sym :rubyguides
การสร้างอาร์เรย์ของสัญลักษณ์
หากคุณต้องการสร้างอาร์เรย์ของสัญลักษณ์ คุณสามารถใช้รหัสนี้:
symbols = %i(a b c) [:a, :b, :c]
วิธีนี้ช่วยให้คุณไม่ต้องพิมพ์เครื่องหมายทวิภาคและจุลภาค
คล้ายกับรุ่นสตริง %w
:
strings = %w(a b c) ["a", "b", "c"]
วิดีโอสัญลักษณ์ทับทิม
สัญลักษณ์ GC (ขั้นสูง)
ข้อเท็จจริงที่น่าสนใจอีกประการเกี่ยวกับสัญลักษณ์ก็คือมีหลายประเภท
เหตุผลก็คือสัญลักษณ์ไม่ใช่ขยะที่รวบรวมก่อน Ruby 2.2 ซึ่งหมายความว่าไม่ได้ล้างข้อมูลออกจากหน่วยความจำเมื่อไม่ต้องการใช้อีกต่อไป เช่น วัตถุ Ruby ทั่วไป (สตริง แฮช อาร์เรย์…)
ดูตัวอย่างได้ที่นี่ :
p Symbol.all_symbols.size # 2443 ('aa'..'aj').map(&:to_sym) GC.start p Symbol.all_symbols.size # 2453
คุณจะสังเกตเห็นว่าจำนวนสัญลักษณ์ทั้งหมดเพิ่มขึ้น 10 ตัว เช่นเดียวกับที่คุณคาดหวังเนื่องจากเรากำลังสร้างสัญลักษณ์ใหม่ 10 ตัว
แต่เนื่องจาก Ruby 2.2 สัญลักษณ์เหล่านี้ถูกลบออกจากหน่วยความจำเนื่องจากเป็นเพียงชั่วคราวและไม่ได้ใช้โดยอย่างอื่นในรหัสนี้
หากคุณลองใช้รหัสนี้ในเวอร์ชันของ Ruby ที่เปิดใช้ Symbol GC การนับสัญลักษณ์ทั้งสองจะเท่ากัน
สัญลักษณ์บางตัวจะไม่ถูกลบออกจากหน่วยความจำ ซึ่งเรียกว่า “สัญลักษณ์อมตะ”
คุณสามารถนับได้โดยใช้โมดูล ObjectSpace:
require 'objspace' ObjectSpace.count_symbols { :mortal_dynamic_symbol=>3, :immortal_dynamic_symbol=>5, :immortal_static_symbol=>3663, :immortal_symbol=>3668 }
สังเกตว่าสัญลักษณ์ที่สร้างขึ้นโดยตรง เช่น :a1
จะกลายเป็นสัญลักษณ์อมตะโดยอัตโนมัติ การสร้างวิธีการใหม่จะสร้าง immortal_static_symbol
. ด้วย ไปกับมัน
แล้วสัญลักษณ์มนุษย์มาจากไหน?
จากสตริงที่แปลงเป็นสัญลักษณ์ด้วย to_sym
วิธีการ
คุณสามารถตรวจสอบได้ด้วยตัวเองโดยใช้ ObjectSpace.count_symbols
.
และหากคุณสงสัยว่า immortal_dynamic_symbol
. คืออะไร มันคือสัญลักษณ์ที่ได้รับการเลื่อนระดับจากมนุษย์เป็นอมตะ สิ่งนี้สามารถเกิดขึ้นได้เมื่อคุณสร้างวิธีการที่มีชื่อสัญลักษณ์มนุษย์
สรุป
ในบทความนี้คุณได้เรียนรู้:
- สัญลักษณ์ไม่เปลี่ยนรูป
- สัญลักษณ์ไม่ใช่ตัวชี้ของค่า แต่เป็นค่าในตัวมันเอง
- สตริงสำหรับข้อมูล &สัญลักษณ์สำหรับข้อมูลประจำตัว
- วิธีการแปลงระหว่างสตริงและสัญลักษณ์
- Symbol GC ถูกนำมาใช้ใน Ruby 2.2 เพื่อล้างสัญลักษณ์ชั่วคราว
หวังว่าคุณจะได้เรียนรู้สิ่งใหม่!
โปรดแชร์โพสต์นี้เพื่อให้เข้าถึงผู้คนได้มากขึ้น 🙂