集合
最后更新于:2022-04-01 01:18:43
* 倾向数组及哈希的字面表示法(除非你需要给构造器传入参数)。
~~~
# 差
arr = Array.new
hash = Hash.new
# 好
arr = []
hash = {}
~~~
* 创建元素为单词(没有空格和特殊符号)的数组时,用 `%w` 而不是 [] 方法。仅当数组有两个及以上元素时才应用这个规则。
~~~
# 差
STATES = ['draft', 'open', 'closed']
# 好
STATES = %w(draft open closed)
~~~
* 当你需要一个符号的数组(并且不需要保持 Ruby 1.9 兼容性)时,使用 `%i`。仅当数组只有两个及以上元素时才应用这个规则。
~~~
# 差
STATES = [:draft, :open, :closed]
# 好
STATES = %i(draft open closed)
~~~
* 避免在 `Array` 和 `Hash` 字面量中的最后一个元素后面使用逗号。特别是元素同一行的情况下
~~~
# 差 - 方面移动、增加和修改参数,但仍不建议使用
VALUES = [
1001,
2020,
3333,
]
# 差
VALUES = [1001, 2020, 3333, ]
# 好
VALUES = [1001, 2020, 3333]
~~~
* 避免在数组中创造巨大的间隔。
~~~
arr = []
arr[100] = 1 # 现在你有一个很多 nil 的数组
~~~
* 当访问数组的首元素或尾元素时,尽量使用 `first` 或 `last`, 而非 `[0]` 或 `[-1]`。
* 当处理的元素没有重复时,使用 `Set` 来替代 `Array` 。 `Set` 实现了无序、无重复值的集合。 `Set` 的方法同数组类一样直观,还可像哈希中那样快速查找元素。
* 尽量用符号来取代字符串作为哈希的键。
~~~
# 差
hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
# 好
hash = { one: 1, two: 2, three: 3 }
~~~
* 避免使用可变的对象作为键值。
* 当哈希的键为符号时,使用 Ruby 1.9 的哈希的字面语法。
~~~
# 差
hash = { :one => 1, :two => 2, :three => 3 }
# 好
hash = { one: 1, two: 2, three: 3 }
~~~
* 但哈希的键有符号也有字符串时,不使用Ruby 1.9的字面量语法。
~~~
# 差
{ a: 1, 'b' => 2 }
# 好
{ :a => 1, 'b' => 2 }
~~~
* 用 `Hash#key?`。不用 `Hash#has_key?`。用 `Hash#value?`。不用 `Hash#has_value?`。松本提到过已经不推荐使用较长的形式了。
~~~
# 差
hash.has_key?(:test)
hash.has_value?(value)
# 好
hash.key?(:test)
hash.value?(value)
~~~
* 在处理应该存在的哈希键时,使用 `Hash#fetch`。
~~~
heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
# 差 - 如果我们打错字的话,我们就无法找到对的英雄了
heroes[:batman] # => "Bruce Wayne"
heroes[:supermen] # => nil
# 好 - fetch 会抛出一个 KeyError 来使这个问题明显
heroes.fetch(:supermen)
~~~
* 在使用 `Hash#fetch` 时,使用第二个参数设置默认值。
~~~
batman = { name: 'Bruce Wayne', is_evil: false }
# 差 - 如果我们仅仅使用 || 操作符,那么当值为假时,我们不会得到预期的结果
batman[:is_evil] || true # => true
# 好 - fetch 在遇到假值时依然正确
batman.fetch(:is_evil, true) # => false
~~~
* 如果求值的代码有副作用或者开销大,尽量用 `Hash#fetch` 加区块而不是直接设定默认值。
~~~
batman = { name: 'Bruce Wayne' }
# 差 - 默认值是立即求值
batman.fetch(:powers, obtain_batman_powers) # obtain_batman_powers 需要复杂的计算
# 好 - 区块是惰性求职,只有当 KeyError 异常时才执行
batman.fetch(:powers) { obtain_batman_powers }
~~~
* 当需要从哈希中同时获取多个键值时,使用 `Hash#values_at`。
~~~
# 差
email = data['email']
username = data['nickname']
# 好
email, username = data.values_at('email', 'nickname')
~~~
* Ruby 1.9 的哈希是有序的,利用这个特性。
* 在遍历一个集合时,不要改动它。
* 当访问集合中的元素时,避免通过 `[n]` 直接访问,尽量使用提供的方法。这样可以防止你对 `nil` 调用 `[]`。
~~~
# 差
Regexp.last_match[1]
# 好
Regexp.last_match(1)
~~~
* 为集合提供存取器时,在访问元素之前采用一种替代的形式,从而防止用户访问的下标是 `nil`。
~~~
# 差
def awesome_things
@awesome_things
end
# 好
def awesome_things(index = nil)
if index && @awesome_things
@awesome_things[index]
else
@awesome_things
end
end
~~~