- 論壇徽章:
- 30
|
本帖最后由 shijiang1130 于 2013-07-19 21:32 編輯
使用 Symbol
正如前邊提到的, Ruby 內(nèi)部一直在使用 Symbol ,比如 Ruby 程序中的各種名字,Symbol本質(zhì)上是 Ruby 符號表中的東西。使用 Symbol 處理名字可以降低 Ruby 內(nèi)存消耗,提高執(zhí)行速度,這點我們在下一篇文章中會看到。
那么 Symbol 對我們有什么用呢?當(dāng)然也是內(nèi)存。使用 String 的開銷太大了,因為每一個String 都是一個對象。想想前邊的例子,一個字符串每出現(xiàn)一次 Ruby 就會創(chuàng)建一個 String 對象。
通常來講,當(dāng)你面臨 String 還是 Symbol 的選擇時,可以參考以下標(biāo)準(zhǔn):
如果使用字符串的內(nèi)容,這個內(nèi)容可能會變化,使用 String
如果使用固定的名字或者說是標(biāo)識符,使用 Symbol
那么什么時候我們會用到名字呢?很多時候都會,比如枚舉值、關(guān)鍵字(哈希表關(guān)鍵字、方法的參數(shù))等等
作為哈希表的 key
哈希表是 Symbol 應(yīng)用最為廣泛的地方。
在ruby中,哈希和數(shù)組類似,一個哈希表是一系列 key/value 對的集合,只不過它的 key 取值范圍更廣泛,可以是任何對象,比如正則表達(dá)式。但通常我們都會取有意義的 key ,比如 String、Symbol 。
下面這個哈希表表示按城市分類的一些機(jī)器的集合。
一個哈希表例子
hosts{
'beijing' => 'machine1',
'shanghai' => 'machine2',
'guangzhou' => 'machine3',
'tianjin' => 'machine4',
'shenzhen' => 'machine5'
}
如果要引用 beijing 的機(jī)器,使用 hosts['beijing'] 。但如果我們程序中要頻繁引用哈希表中 value ,這樣就不大好了,因為 Ruby 對每一次字符串引用都會生成一個 String 對象,累積下來這個開銷是相當(dāng)大的。
我們完全可以使用 Symbol ,因為對于這些 key 來講,我們用的就是名字而已,例如下面hosts[:beijing]
使用 Symbol 作為 key
hosts = {
:beijing => 'machine1',
:shanghai => 'machine2',
:guangzhou => 'machine3',
:tianjin => 'machine4',
:shenzhen => 'machine5'
}
哈希參數(shù)
通常我們定義的函數(shù)的參數(shù)的個數(shù)和順序是寫死的,調(diào)用函數(shù)的時候要確保參數(shù)的個數(shù)、順序匹配,有時候這樣很不方便,使用哈希參數(shù)可以解決這個問題。
ROR 中就大量地運(yùn)用這種方式,也許你已經(jīng)看到了,到處都是 Symbol 和哈希。比如:
使用哈希參數(shù)的方法調(diào)用
link_to 'Show', :action => 'show', :id => product
add_column :products, :price, :decimal,
:precision => 8, :scale => 2, :default => 0
使用哈希參數(shù)的方法可以如下定義,前半部分為固定參數(shù),后面為可變參數(shù),或者干脆全采用哈希參數(shù):
哈希參數(shù)
def my_method(para1, …, options={})
#your code
end
def my_method(options={})
#your code
end
如果你希望設(shè)定一些默認(rèn)參數(shù),并允許調(diào)用者更改這些參數(shù),可以使用哈希對象的 merge! 方法
hsh.merge!( other_hash )。該方法將 other_hash 里內(nèi)容加到 hsh 中,如果other_hash 與 hsh 有重復(fù)的 key ,則 key 在 other_hash 中的 value 覆蓋 hsh 中對應(yīng) key 的 value 。
方法定義-使用默認(rèn)參數(shù)
class Test
def my_method(opts={})
default_opts={:arg1 => 10, :arg2 => "abc"}
default_opts.merge!(opts)
default_opts.each{|key,value| puts "#{key} is #{value}"}
end
end
t = Test.new
t.my_method :arg1=>5, :arg3=>"def"
運(yùn)行結(jié)果
arg1 is 5
arg2 is abc
arg3 is def
原文:
http://www.ibm.com/developerworks/cn/opensource/os-cn-rubysbl/ |
|