所谓容器是指含有一个或多个对象引用的对象。
在开始实现之前,我们需要决定如何在SongList对象中存储歌曲列表。目前有3个明显的选择:(1)使用Ruby的Array(数组);(2)使用Ruby的Hash(散列表);(3)自定义列表结构。
数组类含有一组对象引用。每个对象引用占据数组中的一个位置,并由一个非负的整数索引来标识。
可以通过使用字面量(literal),或显示地创建Array对象,来创建数组。字面量数组(literal array)只不过是处于方括号中的一组对象。
a = [3.14159, "pie", 99] a.class -> Array a.length -> 3 a[0] -> 3.14159 a[1] -> "pie" a[2] -> 99 a[3] -> nil b = Array.new b.class -> Array b.length -> 0 b[0] = "second" b[1] = "array" b -> ["second", "array"]
数组由[]操作符来进行索引。和Ruby的大多数操作符一样,它实际上是一个方法(Array类的一个实例方法),因此可以被子类重载。使用负整数访问数组,则从数组末端开始计数。
a = [1,3,5,7,9] a[-1] -> 9 a[-2] -> 7 a[-99] -> nil
你也可以使用一对数字[start,count]来访问数组。这将返回一个包含从start开始的count个对象引用的新数组。
a = [1,3,5,7,9] a[1,3] -> [3,5,7] a[3,1] -> [7] a[-3,2] -> [5,7]
最后,你还可以使用range来对数组进行索引,其开始和结束位置被两个或3个点分隔开。两个点的形式包含结束位置,而3个点的形式不包含。
a = [1,3,5,7,9] a[1..3] -> [3,5,7] a[1...3] -> [3,5] a[3..3] -> [7] a[-3..-1] -> [5,7,9]
[]操作符有一个相应的[]=操作符,它可以设置数组中的元素。如果下表是单个整数,那么其位置上的元素将被赋值语句右边的东西说替换。造成的任何间隙将由nil来填充。
a = [1,3,5,7,9] -> [1,3,5,7,9] a[1] = 'bat' -> [1,"bat",5,7,9] a[-3] = 'cat' -> [1,"bat","cat",7,9] a[3] = [9,8] -> [1,"bat","cat",[9,8],9] a[6] = 99 -> [1,"bat',"cat",[9,8],9,nil,99]
如果[]=的下标是两个数字(起点和长度)或者是range,那么原数组中的那些元素将被赋值语句右边的东西说替换。如果长度是0,那么赋值语句右边的东西将被插入到数组的起点位置之前,且不会删除任何元素。如果右边本身是一个数组,那么其元素将替换掉原数组对应位置上的东西。如果索引下标选择的元素个数和赋值语句右边的元素个数不一致,那么数组会自动调整其大小。
a = [1,3,5,7,9] -> [1,3,5,7,9] a[2,2] = 'cat' -> [1,3,"cat",9] a[2,0] = 'dog' -> [1,3,"dog',"cat',9] a[1,1] = [9,8,7] -> [1,9,8,7,"dog","cat",9] a[0..3] = [] -> ["dog","cat",9] a[5..6] = 99,98 -> ["dog","cat",9,nil,nil,99,98]
Hashes(也称关联数组、图或者词典)和数组的相似之处在于它们都是被索引的对象引用的集合。不过数组只能用整数来进行索引。不过数组只能用整数来进行索引,而hash可以用任何类型的对象来进行索引,比如字符串、正则表达式等等。当你将一个值存入hash时,其实需要提供两个对象,一个是索引(通常称为键(key)),另一个是值。随后你可以通过键去索引hash,以获得其对应的值。hash中的值可以是任意类型的对象。
下面的例子使用了hash字母符号表示法;处于花括号之间的key=>value配对的列表。
h = {'dog' => 'canine','cat' =>'feline','donkey' =>'asinine'} h.length ->3 h['dog'] -> "canine" h['cow'] = 'bovine' h[12] = 'dodecine' h['cat'] = 99 h ->{"cow"=>"bovine","cat"=99,12=>"dodecine",
"donkey"=>"asinine","dog"=>"canine"}
和数组相比,hashed有一个突出的优点:可以用任何对象做索引。然后它也有一个突出的缺点:它的元素是无序的,因此很难使用hash来实现栈和队列。
hash是Ruby最常用的数据结构之一。