Các dấu ngoặc khác nhau trong Ruby có nghĩa là gì?


85

Trong Ruby, sự khác biệt giữa {}[]?

{} dường như được sử dụng cho cả khối mã và hàm băm.

[]chỉ dành cho mảng?

Tài liệu không rõ ràng lắm.

Câu trả lời:


70

Nó phụ thuộc vào ngữ cảnh:

  1. Khi tự chúng hoặc gán cho một biến, []sẽ tạo mảng và {}tạo hàm băm. ví dụ

    a = [1,2,3] # an array
    b = {1 => 2} # a hash
    
  2. []có thể được ghi đè như một phương thức tùy chỉnh và thường được sử dụng để tìm nạp mọi thứ từ các hàm băm (thư viện tiêu chuẩn thiết lập []như một phương thức trên các hàm băm giống như fetch)
    Cũng có một quy ước rằng nó được sử dụng như một phương thức lớp trong cùng một cách bạn có thể sử dụng một static Createphương thức trong C # hoặc Java. ví dụ

    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
    

    Xem tài liệu về Ruby Hash để biết ví dụ cuối cùng đó.

  3. Đây có lẽ là cái khó nhất - {}cũng là cú pháp cho các khối, nhưng chỉ khi được truyền cho một phương thức BÊN NGOÀI các đối số parens.

    Khi bạn gọi các phương thức không có parens, Ruby sẽ xem xét vị trí bạn đặt dấu phẩy để tìm ra vị trí kết thúc của các đối số (vị trí của các parens, nếu bạn đã nhập chúng)

    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
lưu ý: Tìm nạp băm # không chính xác là Hash # []. {: a => 1,: b => 2} .fetch (: c) IndexError: key not found
tokland 13/02/11

@tokland :ckhông tìm thấy
yyny 27/12/16

"Cũng có một quy ước rằng nó được sử dụng như một phương thức lớp giống như cách bạn có thể sử dụng phương thức Tạo tĩnh trong C # hoặc Java." Đây chính xác là câu trả lời mà tôi đang tìm kiếm. Cũng là một ví dụ kinh điển về điều tôi ghét nhất ở Ruby; bạn phải biết rất nhiều thủ thuật nhỏ khó hiểu để đọc mã Ruby.
Tony

21

Một cách khác, không quá rõ ràng, cách sử dụng []là từ đồng nghĩa với cuộc gọi Proc # và cuộc gọi Method #. Điều này có thể hơi khó hiểu trong lần đầu tiên bạn gặp phải. Tôi đoán lý do đằng sau nó là nó làm cho nó trông giống một lệnh gọi hàm bình thường hơn.

Ví dụ

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

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

9

Nói rộng ra, bạn chính xác. Cũng như hàm băm, phong cách chung là dấu ngoặc nhọn {}thường được sử dụng cho các khối có thể khớp tất cả trên một dòng, thay vì sử dụng do/ endtrên một số dòng.

Dấu ngoặc vuông []được sử dụng làm phương thức lớp trong rất nhiều lớp Ruby, bao gồm String, BigNum, Dir và thật khó hiểu, Hash. Vì thế:

Hash["key" => "value"]

cũng hợp lệ như:

{ "key" => "value" }

3

Dấu ngoặc vuông [] được sử dụng để khởi tạo mảng. Tài liệu cho trường hợp khởi tạo của [] trong

ri Array::[]

Dấu ngoặc nhọn {} được sử dụng để khởi tạo hàm băm. Tài liệu cho trường hợp khởi tạo của {} trong

ri Hash::[]

Dấu ngoặc vuông cũng thường được sử dụng như một phương thức trong nhiều lớp ruby ​​cốt lõi, như Array, Hash, String và các lớp khác.

Bạn có thể truy cập danh sách tất cả các lớp có phương thức "[]" được xác định bằng

ri []

hầu hết các phương thức cũng có phương thức "[] =" cho phép gán mọi thứ, ví dụ:

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

Dấu ngoặc nhọn cũng có thể được sử dụng thay cho "do ... end" trên các khối, như "{...}".

Một trường hợp khác mà bạn có thể thấy dấu ngoặc vuông hoặc dấu ngoặc nhọn được sử dụng - là trong bộ khởi tạo đặc biệt, nơi bất kỳ ký hiệu nào cũng có thể được sử dụng, như:

%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

một vài ví dụ:

[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

Lưu ý rằng bạn có thể xác định []phương thức cho các lớp của riêng mình:

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

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

end

1
@rank.gì?
FeifanZ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.