我在剛接觸符號(Symbol)這個名詞的時候,心裡想的是:
覺得哇~原來寫程式也可以玩emoji(被打..)
現在想起來還真的是蠢到不行,我想就算是新手也沒像我這麼單(愚)純(蠢)吧XD
在Rails專案裡,我們常常看到冒號加上英文字母的用法,例如:name
,age
,party
,policy
def clean_params
params.require(:candidate).permit(:name, :age, :party, :policy)
end
或是Hash
student = {:name => 'Louis', :age =>'18'}
冒號的後面其實也非必要加英文,你要變成:やさしい
,:帥哥
,:123
也是會過的,只是在使用上很不方便且很少見,建議還是用英文字母就好。
其實符號(Symbol)與變數(variable)的命名很像,只是符號前面有加冒號的差別而已。
符號在Ruby裡是很重要的存在,它並不只是像變數命名一樣,只是個'名字'的存在。可以想像成符號就是「有名字的物件」且「無法變更的字串(String)」。
x = 1 #數字物件
x = 'good' #字串物件
x = :good #符號物件
開啟irb來看一下:
# 改變字串
2.6.3 :016 > a = 'hello'
=> "hello"
2.6.3 :017 > a[0]
=> "h"
2.6.3 :018 > b = :hello
=> :hello
2.6.3 :019 > b[0]
=> "h"
2.6.3 :020 > a[0] = 'f'
=> "f"
2.6.3 :021 > a
=> "fello" #字串的第一個字母'h'改成'f'
2.6.3 :022 >
# 改變符號,出現error
2.6.3 :022 > b = :hello
=> :hello
2.6.3 :023 > b[0]
=> "h"
2.6.3 :024 > b[0] = 'f'
NoMethodError (undefined method `[]=' for :hello:Symbol)
記憶體的存取方式也不同:
# 符號(Symbol)每次印出 :name 時,具有唯一性,佔用記憶體位址相同。
2.6.3 :012 > :name.object_id
=> 88028
2.6.3 :013 > :name.object_id
=> 88028
# 字串(String)每次印出"name"時,他的object_id都會不同,佔用的記憶體位址也不同。
2.6.3 :014 > 'name'.object_id
=> 70183486959360
2.6.3 :015 > 'name'.object_id
=> 70183486974200
每個Symbol產生時,在Ruby裡就會產生一個獨立的object_id,直到程式結束為止,而字串在每次產生的時候,都會產生一個新的object_id,這也是為何「字串的內容可以被修正,但符號不行。」的原因。
也因為每次取用一次String,就得產生一個新的object_id,很佔用記憶體空間,Symbol則是直接取用一開始建立的object_id,所以字串的效能稍微差一點。
# 字串轉成 Symbol
2.6.3 :025 > 'name'.to_sym
=> :name
# Symbol 轉成字串
2.6.3 :026 > :name.to_s
=> "name"
參考資料:
PJChen的私房菜
Ruby語法放大鏡
“When there’s that moment of ‘Wow, I’m not really sure I can do this,’ and you push through those moments, that’s when you have a breakthrough.”
— Marissa Mayer, CEO of Yahoo
本文同步發佈於: https://louiswuyj.tw/