Ruby中全域性變數,例項變數,區域性變數,類變數,Symbol對比
Ruby中全域性變數,例項變數,類變數,Symbol這些東西經常和其它語言如Java有很大不同,很容易搞混,所以做個總結。
首先是不些命名的約定,注意這些約定是強制性的:
格式 | 名稱 | 是否需初始化 | 作用範圍 | 舉例 |
---|---|---|---|---|
$開頭 | 全域性變數 | 不用,初始前為nil | 從定義時開始,直到程式結束 | $user |
@開頭 | 例項變數 | 不用,初始前為nil | self | @user |
@@開頭 | 類變數 | 要先定義,直接使用異常 | 內部直接使用,外部用:: | @@user |
[a-z] or _開頭 | 區域性變數 | 不會在初始化前賦nil,要先賦值再呼叫。偽變數:self, nil, __FILE__等 | 定義的類、模組、方法的內部,但在類、模組、方法間不能共享 | user |
[A-Z] | 常量 | 只能被賦值一次,多次賦值會警告,但不報錯 | 內部,外部均可。外部訪問”類名::常量名” | USER |
:開頭 | Symbol | 不用 | 內外 | :user |
區域性變數時注意:
1、可以定義頂層區域性變數,但在類、方法、模組定義內仍無法訪問該變數;
2、區域性變數不可以在內部類、子類中訪問;類中的方法不可以訪問該類中定義的區域性變數(平級);
3、在宣告區域性變數的類、模組、方法內,區域性變數從宣告該變數處開始生效,隨類、方法、模組的定義結束而結束;
全域性變數時注意:
1、儘量少用,因為他會造成模組間的強耦合
例項變數時注意:
1、例項變數通常在方法中定義;
當在方法中宣告例項變數時,該例項變數事實上屬於該方法所在的類,而不是該方法;
雖然例項變數是屬於類的,但大部分時候我們都是在該類的方法裡定義例項變數;
2、Java在建立物件時一次為該物件的所有例項變數都分配了相應的記憶體空間;
Ruby語言裡的物件完全是動態的,建立物件時該物件沒有任何例項變數,直到執行到為例項變數定義時,該物件才動態增加該例項變數;
3、例項變數的訪問範圍總是:private,即在類定義內對例項變數的賦值和讀取沒有限制;在類外訪問例項變數時,則可以通過方法來訪問
4、例項變數永遠都不能暴露為public,只能通過類方法(類名.方法名)暴露
5、模組中定義例項變數,可以混入該模組中的類中。即模組中的類可以共享模組中定義的例項變數
類變數時注意:
1、一個類、其子類、它們的例項:的同名類變數共享了同一塊記憶體區域(都引用了同一個變數);
2、模組中定義的類變數,可以混入該模組中的類。即模組中的類可以共享模組中定義的類變數
Ruby類中變數都是私有的,方法預設是public的
Symbol時注意:
1、Symbol就是例項變數、方法、類等的名字
2、如果有一個方法叫move_left,則會自動生成一個symbol叫:move_left。
3、Ruby內部維持一個Symbol Table來儲存symbol,可以呼叫Symbol.all_symbols來檢視有哪些。
4、每個String物件都是不同的,即便他們包含了相同的字串內容;而對於 Symbol 物件,一個名字(字串內容)唯一確定一個 Symbol 物件。
5、Symbol不用宣告,系統會自動惟一。它僅僅是一個名字和內部ID。Symbols非常有用因為在Ruby程式中symbol始終指向同一個物件。
類變數與常量區別:
1、類變數可以重複賦值;常量重複賦值時發出警告(不是錯誤);
2、類變數預設是protected的,不能在類外部直接引用;(可在繼承類中以用或賦值);
類變數與例項變數區別:
1、在類範圍內定義的類變數,可以在該類的方法中訪問;而例項變數則不行;
2、類變數可在子類中引用或賦值,但例項變數可在類範圍內直接引用或賦值;
什麼時候需要用symbol?
1、如果物件的內容(字元的序列)非常重要,就使用string
2、如果物件的一致性身份很重要,就用symbol
3、被大量重複使用的內容,如hash中的key一般用symbol
symbol內部是一個整數,可以加大hash檢索速度
在ruby中,靜態變數的定義,應遵守以下規則:
必須以 @@開頭。
類變數在類之外無法訪問,只能通過相關的方法進行訪問。即提供相應的get set 方法進行訪問
類變數必須進行初始化,但其型別在執行的過程中是可以變化的
再說類變數:
不能通過物件名呼叫,只能通過類名來直接呼叫。
即,在方法外不能直接訪問類變數,而只能通過類方法進行間接訪問。訪問的時候,不能使用變數進行訪問,而應使用類名進行訪問。
#類變數和類方法;類變數,類方法在 Java/C# 裡與之相對應的是 static變數,static方法 class Student@@count=0
def initialize
@@count+=1
end
#定義類方法要在方法名前加上類名和一個點號“.” def Student.student_count
puts "This class have #@@count students."
end
end
p1=Student.new
p2=Student.new
Student.student_count # This class have 2 students.
p3=Student.new
p4=Student.new
Student.student_count # This class have 4 students.