14

[]在 Ruby 中经常遇到方括号语法,但它似乎从来没有做同样的事情。任何人都可以列出Ruby 中方括号的所有不同用途,[]以便我能够理解这个看似无穷无尽的小符号吗?(一个符号怎么可能做到这么多,而不会让 Ruby 解释器感到困惑?)

例子:

  • [][]=方法
  • %q[...]
  • [1,2,3][0]
  • hash["a"] = 3
  • ary = []
  • /[^A-Fa-f0-9]/
  • "Is a string"[5,3]
4

3 回答 3

12

方括号有两种严格的上下文和一种可选的上下文:

定义数组
数组,即提供元素的有序列表的数据结构,可以在代码中使用类似的语法来指定[1,2,3]1这将创建一个包含三个元素、和的数组2,并且3完全按照该顺序。然后,您可以使用迭代器函数中的一个来迭代数组,each或者map您可以通过其索引 id 直接访问特定元素,如下所示。

访问数组和哈希中的元素
哈希(在其他语言中也称为哈希图、字典或关联数组)也包含类似于数组的元素。与此不同的是,它们存储数据的方式是无序的。数据不像数组那样通过整数 id 访问,而是使用任意键(通常是符号或字符串)。这与 PHP 中使用相同的 Array 类型的 PHP 不同。

这种对数据的访问是通过调用的方法来促进的[][]=对于散列和数组。

my_array = [:a, :b, :c]
second_element = my_array[1]
# => :b
# notice that the first element in arrays always has the index 0

my_hash = {:a => 1, :b => 2, :c => 3}
element_of_b = my_hash[:b]
# => 2

This is the common use case for the brackets. In Ruby code, you might sometimes see other classes implementing the bracket functions. They do so to allow an access similar to either arrays or hashes and it is then generally expected that these classes behave similar to those but this is in no way enforced. See also Duck Typing.

% Notation
Ruby has a third syntax to create strings (and other objects) apart from the common. Using this syntax, the literal string in code are not enclosed by " or ' but use a special delimiter. It starts with a percent sign, a single character specifying the object to be created and almost any character to chose as a delimiter:

a = %w[foo bar baz]
b = %w{foo bar baz}
c = %wxfoo bar bazx
d = ["foo", "bar", "baz"]

All three example create the same array. Please see the some documentation on how to use this syntax and which other modifier characters are available in Ruby.

While it is common to use brackets here, it is on no way required and can be substituted if required. It is just advisory here as the most common usage of this notation is to create an array of elements from a whitespace-seperated string (as seen above). As such, the usage of brackets makes it further clear that an array is returned as the syntax looks similar to the basic array specification.

于 2012-06-04T07:22:14.750 回答
12

Okay, just for my own notes I have gone and had a closer look at this and, building on Holger Just's answer, come up with the following: the use of square brackets in Ruby can be divided into 6 uses, 3 of them a part of Ruby's method definitions and 3 of them semantic constructs.

Method definition

Object creation via class methods Array::[], Hash::[]

Array.[](1,2,3) #=> [1,2,3]                        #Un-sugared notation
Array["a","b","c"] #=> ["a","b","c"]               #Sugared equivalent
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}  

Nothing to do with literal constructors, although it does the same thing.

Element reference via instance methods Array#[], Bignum#[], Continuation#[], Fixnum#[], Hash#[], MatchData#[], Method#[], Proc#[], String#[], Struct#[], Symbol#[], Thread#[], and class methods Dir::[], ENV::[]

ary = [1,2,"abc", [15,16,[26,27]]]  
ary.[](2) #=> "abc"                #Un-sugared notation
ary[2] #=> "abc"                   #Sugared equivalent
ary[0,2] #=> [1,2]  
ary[3][2][1] #=> 26  
[1,2,3][0] #=> 1  
"Is a string"[7,3] #=> "rin"  

Element assignment via instance methods Array#[]=, Hash#[]=, String#[]=, Struct#[]=, Thread#[]=, and class method ENV::[]=

ary = [1,2,3]  
ary.[]=(1,"abc") #=> [1,"abc",3]    #un-sugared notation
ary[2] = "def" #=> [1,"abc","def"]  #Sugared equivalent
hash = {"a"=>1, "b"=>2}  
hash["a"] = 3 #=> {"a"=>3, "b"=>2}  

Semantic constructs

Object creation via the array literal constructor

ary = []  

There are a bunch of literal constructors in Ruby that create an object of the relevant class via the use of (usually) a simple symbol pair, square brackets being the literal constructor for array objects: Array [], Hash {}, Proc ->(){}, Range .. and ..., Regexp //, String "" and '', Symbol : and :"".

Object creation via the % notation

%q[hello there you] #=> "hello there you"           # String % notation  
%w[hello there you] #=> ["hello", "there", "you"]   # Array % notation  

It is not, strictly speaking, square-bracket notation, but rather two-symbol-pair notation of which you can use square brackets if you wish. So %q@hello there you@ is equally valid.

Ruby's regular expressions

/[^A-Fa-f0-9]/  

Square brackets indicate character classes in Ruby regular expressions.

I did find another use of the [], as a pattern for use in the Dir::glob method, but its supposed to act exactly as it does in regular expressions. Still, it indicates that there are possibly more uses hidden away in Ruby's 1500+ methods.

于 2012-06-07T14:27:38.320 回答
0

handy syntax for instantiating structs with square brackets

irb(main):001:0> Point = Struct.new(:x, :y)                         
=> Point                      
irb(main):002:0> point = Point[1,2]                                 
=> #<struct Point x=1, y=2>   
irb(main):003:0> point.x                   
=> 1                           
irb(main):004:0> point.y                    
=> 2     
于 2022-01-05T21:25:48.837 回答