傾向數(shù)組及哈希的字面表示法(除非你需要給構(gòu)造器傳入?yún)?shù))。
# 差
arr = Array.new
hash = Hash.new
# 好
arr = []
hash = {}
創(chuàng)建元素為單詞(沒(méi)有空格和特殊符號(hào))的數(shù)組時(shí),用?%w
?而不是 [] 方法。僅當(dāng)數(shù)組有兩個(gè)及以上元素時(shí)才應(yīng)用這個(gè)規(guī)則。
# 差
STATES = ['draft', 'open', 'closed']
# 好
STATES = %w(draft open closed)
當(dāng)你需要一個(gè)符號(hào)的數(shù)組(并且不需要保持 Ruby 1.9 兼容性)時(shí),使用?%i
。僅當(dāng)數(shù)組只有兩個(gè)及以上元素時(shí)才應(yīng)用這個(gè)規(guī)則。
# 差
STATES = [:draft, :open, :closed]
# 好
STATES = %i(draft open closed)
避免在?Array
?和?Hash
?字面量中的最后一個(gè)元素后面使用逗號(hào)。特別是元素同一行的情況下
# 差 - 方面移動(dòng)、增加和修改參數(shù),但仍不建議使用
VALUES = [
1001,
2020,
3333,
]
# 差
VALUES = [1001, 2020, 3333, ]
# 好
VALUES = [1001, 2020, 3333]
避免在數(shù)組中創(chuàng)造巨大的間隔。
arr = []
arr[100] = 1 # 現(xiàn)在你有一個(gè)很多 nil 的數(shù)組
當(dāng)訪問(wèn)數(shù)組的首元素或尾元素時(shí),盡量使用?first
?或?last
, 而非?[0]
?或?[-1]
。
當(dāng)處理的元素沒(méi)有重復(fù)時(shí),使用?Set
?來(lái)替代?Array
?。?Set
?實(shí)現(xiàn)了無(wú)序、無(wú)重復(fù)值的集合。?Set
?的方法同數(shù)組類一樣直觀,還可像哈希中那樣快速查找元素。
盡量用符號(hào)來(lái)取代字符串作為哈希的鍵。
# 差
hash = { 'one' => 1, 'two' => 2, 'three' => 3 }
# 好
hash = { one: 1, two: 2, three: 3 }
避免使用可變的對(duì)象作為鍵值。
當(dāng)哈希的鍵為符號(hào)時(shí),使用 Ruby 1.9 的哈希的字面語(yǔ)法。
# 差
hash = { :one => 1, :two => 2, :three => 3 }
# 好
hash = { one: 1, two: 2, three: 3 }
但哈希的鍵有符號(hào)也有字符串時(shí),不使用Ruby 1.9的字面量語(yǔ)法。
# 差
{ a: 1, 'b' => 2 }
# 好
{ :a => 1, 'b' => 2 }
用?Hash#key?
。不用?Hash#has_key?
。用?Hash#value?
。不用?Hash#has_value?
。松本提到過(guò)已經(jīng)不推薦使用較長(zhǎng)的形式了。
# 差
hash.has_key?(:test)
hash.has_value?(value)
# 好
hash.key?(:test)
hash.value?(value)
在處理應(yīng)該存在的哈希鍵時(shí),使用?Hash#fetch
。
heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
# 差 - 如果我們打錯(cuò)字的話,我們就無(wú)法找到對(duì)的英雄了
heroes[:batman] # => "Bruce Wayne"
heroes[:supermen] # => nil
# 好 - fetch 會(huì)拋出一個(gè) KeyError 來(lái)使這個(gè)問(wèn)題明顯
heroes.fetch(:supermen)
在使用?Hash#fetch
?時(shí),使用第二個(gè)參數(shù)設(shè)置默認(rèn)值。
batman = { name: 'Bruce Wayne', is_evil: false }
# 差 - 如果我們僅僅使用 || 操作符,那么當(dāng)值為假時(shí),我們不會(huì)得到預(yù)期的結(jié)果
batman[:is_evil] || true # => true
# 好 - fetch 在遇到假值時(shí)依然正確
batman.fetch(:is_evil, true) # => false
如果求值的代碼有副作用或者開(kāi)銷大,盡量用?Hash#fetch
?加區(qū)塊而不是直接設(shè)定默認(rèn)值。
batman = { name: 'Bruce Wayne' }
# 差 - 默認(rèn)值是立即求值
batman.fetch(:powers, obtain_batman_powers) # obtain_batman_powers 需要復(fù)雜的計(jì)算
# 好 - 區(qū)塊是惰性求職,只有當(dāng) KeyError 異常時(shí)才執(zhí)行
batman.fetch(:powers) { obtain_batman_powers }
當(dāng)需要從哈希中同時(shí)獲取多個(gè)鍵值時(shí),使用?Hash#values_at
。
# 差
email = data['email']
username = data['nickname']
# 好
email, username = data.values_at('email', 'nickname')
Ruby 1.9 的哈希是有序的,利用這個(gè)特性。
在遍歷一個(gè)集合時(shí),不要改動(dòng)它。
當(dāng)訪問(wèn)集合中的元素時(shí),避免通過(guò)?[n]
?直接訪問(wèn),盡量使用提供的方法。這樣可以防止你對(duì)?nil
?調(diào)用?[]
。
# 差
Regexp.last_match[1]
# 好
Regexp.last_match(1)
為集合提供存取器時(shí),在訪問(wèn)元素之前采用一種替代的形式,從而防止用戶訪問(wèn)的下標(biāo)是?nil
。
# 差
def awesome_things
@awesome_things
end
# 好
def awesome_things(index = nil)
if index && @awesome_things
@awesome_things[index]
else
@awesome_things
end
end
更多建議: