Ruby的语法和语言特性总结

2019-09-25 09:36:14王冬梅

1.4 函数

def tell_the_truth
 true
end

每个函数都会返回结果,如果没有显式指定返回值,函数就将退出函数前最后处理的表达式的值返回。函数也是个对象,可以作为参数传给其他函数。

1.5 数组

和Python一样,Ruby的数组也是用中括号来定义,如animals = ['lion', 'tiger', 'bear'];负数下标可以返回倒数的元素,如animals[-1] => "bear";通过指定一个Range对象来获取一个区段的元素,如animals[1..2] => ['tiger', 'bear']。此外,数组元素可以互不相同,多为数组也不过是数组的数组。数组拥有极其丰富的API,可用其实现队列、链表、栈、集合等等。

1.6 散列表

numbers = {2 => 'two', 5 => 'five'}
stuff = {:array => [1, 2, 3], :string => 'Hi, mom!'}
# stuff[:string] => "Hi, mom!"

散列表可以带任何类型的键,上述代码的stuff的键较为特殊——它是一个符号(symbol),前面带有冒号标识符。符号在给事物和概念命名时很好用,例如两个同值字符串在物理上不同,但相同的符号却是同一物理对象,可以通过反复调用'i am string'.object_id和:symbol.object_id来观察。另外,当散列表用作函数最后一个参数时,大括号可有可无,如tell_the_truth :profession => :lawyer。

2. 面向对象
2.1 代码块

代码块是没有名字的函数(匿名函数),可以用作参数传递给函数。代码块只占一行时用大括号包起来,占多行是用do/end包起来,可以带若干个参数。

3.times {puts 'hehe'} # 输出3行hehe
['lion', 'tiger', 'bear'].each {|animal| puts animal} # 输出列表的内容

上面的times实际上是Fixnum类型的方法,要自己实现这样一个方法非常容易:

class Fixnum
 def my_times
  i = self
   while i > 0
    i = i - 1
    yield
  end
 end
end
3.my_times {puts 'hehe'} # 输出3行hehe

这段代码打开一个现有的类,向其中添加一个自定义的my_times方法,并用yield调用代码块。在Ruby中,代码块不仅可用于循环,还可用于延迟执行,即代码块中的行为只有等到调用相关的yield时才会执行。代码块充斥于Ruby的各种库,小到文件的每一行,大到在集合上进行各种复杂操作,都是由代码块来完成的。

2.2 类

调用一个对象的class方法可以查看其类型,调用superclass可以查看这个类型的父类。下图展示了数字的继承链,其中横向箭头表示右边是左边实例化的对象,纵向箭头表示下边继承于上边。Ruby的一切事物都有一个共同的祖先Object。

2016612151714257.png (685×376)

最后通过一个完整的实例——定义一棵树,来看下Ruby的类如何定义和使用,该注意的点都写在注释里面了。