前情提要:
第六天我們透過Ruby代碼練習public,protected和privatemethod時,發現冒號在前面的參數,:mydraft,:myspace,這些就是符號Symbol。在今天,我們就來解釋Symbol吧!
Ruby經典面試題目#07
符號和字串有什么不同?What’s difference between symbol and string?
還記得我之前IT邦文章在Ruby on Rails項目例子中研究ruby的gem套件時,我發現這兩者寫法的功能是一樣的:
:image_directory => 'tingsimage'
功能跟下者一樣:
image_directory: 'tingsimage'
:冒號在前面,意思是符號
冒號在后面:,意思是給值
當時的發現,也是造就本篇文章想進一步探討跑來跑去的小淘氣冒號的原因。
比一比符號symbol字串string
意思有名字的符號物件指向字串物件的變數(leafor)
可不可變不可變immutable可變mutable
修改數組不可使用[]=方法可使用[]=方法修改字串
數組方法可使用[]取得數組內的字元可使用[]取得數組內的字元
字元方法可使用.length .upcase .downcase可使用.length .upcase .downcase
符號與字串轉換符號轉字串.to_s字串轉符號.to_sym
我們來用代碼實驗看看:
tingsmessage =“This is my 7th article!”
tingsmessage這個變數,指向“This is my 7th article!”這個字串物件,變數的用意,就是讓我的字串物件可以隨時做調整。(明天我的message跑馬燈就會換成第八天的招呼啰!)
如果我們把它變成::tingsmessage的符號呢?
它就會變成Symbol類別下的物件實體,名字叫做tingsmessage。
來用代碼實作:
:tingsmessage這個符號,名字有12個字元,名字的第1個字母是t(數組位置[0]代表第1個),第2個字母是i…以此類推:
p:tingsmessage.length #12
p:tingsmessage.upcase #TINGSMESSAGE
p:tingsmessage[0] #t
p:tingsmessage[1] #i
而tingsmessage這個每天都會變來變去的變數,所指向的字串,一共有23個字元:(不信你數數看!)
tingsmessage =“This is my 7th article!”
p tingsmessage.length #23
p tingsmessage.upcase #THIS IS MY 7TH ARTICLE!
p tingsmessage[0] #t
p tingsmessage[1] #h
身為變數的好處就是可以任意修改。我們來試試改字母:
tingsmessage[1] =“Z”
p tingsmessage[1] #Z
p tingsmessage #TZis is my 7th article!
然而符號呢?
:tingsmessage[1]=“Z”
#undefined method `[]=' for:tingsmessage:Symbol(NoMethodError)
符號會找不到[]=方法修改字串。你可以想像,符號就如同我們在護照上的名字,是不能修改的。(因為已經被定義在國際間海關通用的數據庫了。)
符號的好處是專一,它被寫在程序里固定的內存位置,所以提取性能較高。我們可以用object_id的方法來實驗:
3.times do
p:tingsmessage.object_id
end
印出結果:
1041308
1041308
1041308
而變來變去的變數每次都在內存里面,搬家到不同位置:
3.times do
p“tingsmessage”.object_id
end
印出結果:
46936214509440
46936214509260
46936214509180
在前述比較表,符號和字串之間可以互相轉換的。
p:tingsmessage #:tingsmessage
p:tingsmessage.to_s # tingsmessage前面的冒號已經不見了!
p tingsmessage # TZis is my 7th article!
p tingsmessage.to_sym #:TZis is my 7th article!前面多一個冒號
何時使用符號Symbol
需要性能較高地傳遞參數時,例如在之前我們使用rails建立項目,餐廳名字、電話等…,這些數據庫字段的名稱是固定不變的:
def restaurant_params
params.require(:restaurant).permit(:name,:address,:phone,:website,:image)
end
回到文初一開頭,我終于明白,
{:image_directory => 'tingsimage'}
其實是符號Symbol用在Hash(外圍被大括號{}包著)里,是變數給值=>的意思。
今天超級比一比,就到這里結束啦(xcsjbj)!
比一比符號symbol字串string
意思有名字的符號物件指向字串物件的變數
可不可變不可變immutable可變mutable
修改數組不可使用[]=方法可使用[]=方法修改字串
數組方法可使用[]取得數組內的字元可使用[]取得數組內的字元
字元方法可使用.length .upcase .downcase可使用.length .upcase .downcase
符號與字串轉換符號轉字串.to_s字串轉符號.to_sym
===