要了解Symbol (符號)和 String(字串) 的差別,
首先,我們得先複習一下Variable(變數) 和 String(字串):
變數,它本身並沒有形態。你可以把它想像成是「一張有寫著名字的標籤,貼在某個東西上面」,被貼的那個東西有形態,但標籤本身沒有。
- from 為你自己學 Ruby and Rails
str = "I am string"
# str 是一個變數,是個標籤,它被貼在"I am string"這個字串上面。
str.class => String
str.object_id => 70345293831900
String 是一個字串物件,同時也是一串由字母(characters)
所組成的陣列(Array),所以許多陣列上的方法也都適用。
# 字串的內容可以任意修改。
str[3] => "m"
str.reverse => "gnirts ma I"
str[0] = "A"
p str => "A am string"
A Symbol is the most basic Ruby object you can create. It's just a name and an internal ID. - rubylearing.com
Symbol objects represent names and some strings inside the Ruby interpreter. from ruby-doc.org
Symbol(符號):
讓我們來看看下面的範例:
1. :name 是一個物件
:name.class => Symbol
:name.object_id => 87708
2. :name 是一個值,有他自己的名字,:name。
x = 2
=> 2
x = :name
=> :name
:name = "string"
=> syntax error, unexpected '=' ...
#每次在印出"name"字串時,所得到的object_id 都不同
p "name".object_id => 70143757662660
p "name".object_id => 70143757662560
p "name".object_id => 70143757662460
#在印出:name的時候,只有一個object_id(唯一性)。
p :name.object_id => 1057308
p :name.object_id => 1057308
p :name.object_id => 1057308
:name[0] => "n"
:name.reverse => NoMethodError
:name[0] = A => NameError (uninitialized constant A)
:name[0] = a => NameError (undefined local variable or method `a' for main:Object)
Transform between Symbol and String
name = :name
p name
str = name.to_s
p str
s2sym_1 = str.to_sym
s2sym_2 = str.intern
p s2sym_1 # convert from .to_sym
p s2sym_2 # convert from .intern
Symbols are names - names of instance variables, names of methods, names of classes. - rubylearing.com
Thus if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
- ruby-doc.org
你可以用Google翻譯一下上面文字,或是直接看翻譯蒟蒻:
有四種方式會產生Symbol:
class Cat
@weight
Hi = 1
def meow
end
end
puts :Cat.object_id.to_s + " is from class Cat"
puts :weight.object_id.to_s + " is from instance variable weight"
puts :Hi.object_id.to_s + " is from constant Hi"
puts :meow.object_id.to_s + " is from method meow"
# 在Repl.it上的執行結果
1047588 is from class Cat
1048668 is from instance variable weight
1048228 is from constant Hi
1048348 is from method meow
什麼時候該用Symbol,什麼時候該用String?
If you use the contents of a string, this content may change, using a string.
If you use a fixed name or an identifier, use the symbol. - IBM opensource
簡單來說:
當你存放的內容是會變動時,使用String。
當你存放固定資料或是希望資料具有唯一性時,使用Symbol。
Symbol是用在什麼地方呢?
#這是在存取資料時常用的Hash
profile = {name: 'kk', age: 18, email: 'kk@5xruby.tw'}
# 改成舊式的寫法:
profile = {:name => 'kk', :age => 18, :email => 'kk@5xruby.tw'}
#這是在Rails中常見的Migration檔的內容:
class CreateTodos < ActiveRecord::Migration[5.2]
def change
create_table :todos do |t|
t.string :title
t.string :description
t.references :user, foreign_key: true
t.timestamps
end
end
end
#這是在Rails中常見的Model中的檔案內容:
class Todo < ApplicationRecord
belongs_to :user
validates :title, :description, presence: true
end
冷知識:Symbol 命名的注意事項
Symbol 在命名時,不接受"\"字元:
#irb Mode
:name => :name
:n\ame => SyntaxError
以上,就是Symbol (符號)和 String(字串) 的差別。
鐵人賽,我們下次再見!!