วงเล็บต่างๆใน Ruby หมายถึงอะไร?


85

ใน Ruby ความแตกต่างระหว่าง{}และ[]อย่างไร?

{} ดูเหมือนว่าจะใช้สำหรับทั้งบล็อกโค้ดและแฮช

มี[]เพียง แต่สำหรับอาร์เรย์?

เอกสารไม่ชัดเจนมาก

คำตอบ:


72

ขึ้นอยู่กับบริบท:

  1. เมื่ออยู่ในตัวเองหรือกำหนดให้กับตัวแปร[]จะสร้างอาร์เรย์และ{}สร้างแฮช เช่น

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []สามารถแทนที่เป็นวิธีการที่กำหนดเองได้และโดยทั่วไปจะใช้เพื่อดึงสิ่งต่างๆจากแฮช (ไลบรารีมาตรฐานตั้งค่า[]เป็นวิธีการบนแฮชซึ่งเหมือนกับfetch)
    นอกจากนี้ยังมีหลักการที่ใช้เป็นวิธีการคลาสเหมือนกัน วิธีที่คุณอาจใช้static Createวิธีการใน C # หรือ Java เช่น

    a = {1 => 2} # create a hash for example
    puts a[1] # same as a.fetch(1), will print 2
    
    Hash[1,2,3,4] # this is a custom class method which creates a new hash
    

    ดูเอกสาร Ruby Hashสำหรับตัวอย่างสุดท้ายนั้น

  3. นี่อาจเป็นสิ่งที่ยุ่งยากที่สุด - {}ยังเป็นไวยากรณ์สำหรับบล็อก แต่เมื่อส่งไปยังเมธอดที่อยู่นอกอาร์กิวเมนต์เท่านั้น

    เมื่อคุณเรียกใช้เมธอดโดยไม่มี parens Ruby จะดูที่ที่คุณใส่เครื่องหมายจุลภาคเพื่อดูว่าอาร์กิวเมนต์สิ้นสุดที่ใด (parens จะอยู่ที่ไหนคุณเคยพิมพ์หรือไม่)

    1.upto(2) { puts 'hello' } # it's a block
    1.upto 2 { puts 'hello' } # syntax error, ruby can't figure out where the function args end
    1.upto 2, { puts 'hello' } # the comma means "argument", so ruby sees it as a hash - this won't work because puts 'hello' isn't a valid hash
    

2
หมายเหตุด้านข้าง: Hash # fetch ไม่ใช่ Hash # [] {: a => 1,: b => 2} .fetch (: c) IndexError: ไม่พบคีย์
tokland

@tokland :cไม่พบ
yyny

"นอกจากนี้ยังมีข้อตกลงที่ใช้เป็นเมธอดคลาสในลักษณะเดียวกับที่คุณอาจใช้เมธอดสร้างแบบคงที่ใน C # หรือ Java" นี่คือคำตอบที่ฉันกำลังมองหา ยังเป็นตัวอย่างคลาสสิกของสิ่งที่ฉันเกลียดที่สุดเกี่ยวกับ Ruby; คุณต้องรู้เทคนิคเล็ก ๆ น้อย ๆ ที่คลุมเครือมากมายในการอ่านรหัส Ruby
Tony

22

อีกประการหนึ่งที่ไม่ชัดเจนนักการใช้งาน[]คือคำพ้องความหมายสำหรับ Proc # call และ Method # call สิ่งนี้อาจทำให้สับสนเล็กน้อยในครั้งแรกที่คุณพบ ฉันเดาว่าเหตุผลเบื้องหลังคือมันทำให้ดูเหมือนเป็นการเรียกใช้ฟังก์ชันปกติ

เช่น

proc = Proc.new { |what| puts "Hello, #{what}!" }
meth = method(:print)

proc["World"]
meth["Hello",","," ", "World!", "\n"]

9

พูดอย่างกว้าง ๆ คือคุณพูดถูก เช่นเดียวกับแฮชสไตล์ทั่วไปคือวงเล็บปีกกา{}มักจะใช้สำหรับบล็อกที่สามารถใส่ทั้งหมดลงบนบรรทัดเดียวแทนการใช้do/endข้ามหลายบรรทัด

วงเล็บเหลี่ยม[]ถูกใช้เป็นเมธอดคลาสในคลาส Ruby มากมายรวมถึง String, BigNum, Dir และ Hash นั่นเอง ดังนั้น:

Hash["key" => "value"]

ใช้ได้เช่นเดียวกับ:

{ "key" => "value" }

3

วงเล็บเหลี่ยม [] ใช้เพื่อเริ่มต้นอาร์เรย์ เอกสารสำหรับ initializer case ของ [] อยู่ใน

ri Array::[]

วงเล็บปีกกา {} ใช้เพื่อเริ่มต้นแฮช เอกสารสำหรับ initializer case ของ {} อยู่ใน

ri Hash::[]

วงเล็บเหลี่ยมมักใช้เป็นวิธีการในคลาสทับทิมหลักเช่น Array, Hash, String และอื่น ๆ

คุณสามารถเข้าถึงรายการคลาสทั้งหมดที่มีเมธอด "[]" กำหนดด้วย

ri []

วิธีการส่วนใหญ่ยังมีเมธอด "[] =" ที่อนุญาตให้กำหนดสิ่งต่างๆเช่น:

s = "hello world"
s[2]     # => 108 is ascii for e
s[2]=109 # 109 is ascii for m
s        # => "hemlo world"

นอกจากนี้ยังสามารถใช้วงเล็บปีกกาแทน "do ... end" บนบล็อกเป็น "{... }" ได้อีกด้วย

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

%w{ hello world } # => ["hello","world"]
%w[ hello world ] # => ["hello","world"]
%r{ hello world } # => / hello world /
%r[ hello world ] # => / hello world /
%q{ hello world } # => "hello world"
%q[ hello world ] # => "hello world"
%q| hello world | # => "hello world"

2

ตัวอย่างบางส่วน:

[1, 2, 3].class
# => Array

[1, 2, 3][1]
# => 2

{ 1 => 2, 3 => 4 }.class
# => Hash

{ 1 => 2, 3 => 4 }[3]
# => 4

{ 1 + 2 }.class
# SyntaxError: compile error, odd number list for Hash

lambda { 1 + 2 }.class
# => Proc

lambda { 1 + 2 }.call
# => 3

2

โปรดทราบว่าคุณสามารถกำหนด[]วิธีการสำหรับคลาสของคุณเองได้:

class A
 def [](position)
   # do something
 end

 def @rank.[]= key, val
    # define the instance[a] = b method
 end

end

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