- 分享
- 0
- 人气
- 0
- 主题
- 7
- 帖子
- 4707
- UID
- 82675
- 积分
- 5108
- 阅读权限
- 22
- 注册时间
- 2007-6-18
- 最后登录
- 2021-7-27
- 在线时间
- 5767 小时
|
作者 : Super-Tomato
已經擱筆多時的我今天看到佳里論壇的一篇覺得蠻有探討性的問題所以就決定寫一寫. 問題是這樣的
为何Action Script 对于String 类或Number 类不能够直接使用call by reference的方法去操作 ?
Actionscript 的始祖是 Java, 但很多編程員在寫了程式那麼久, 始終不了解 call by reference 怎麼在 Java 系列的語言上用不到? 在這裡就寫些小心得.
由於寫日誌的目的在於分享, 所以就從簡單開始寫起, 方便一些學習中的新手比較容易掌握到概念.
任何編程員都在開始前面的幾堂課認識到 "無變數(variable)不成程式" 的概念, 還有就是所有變數會把所有賦予的值儲存在記憶體中, 就如 a = 100, b = 200 那麼 a 就代表著 100, b 代表 200. (在程式中 = 並非數學中的等於)
再來我就用個簡單的圖片來表示記憶體儲存方式
紅色代表記憶體位置編號
藍色代表程式中的變數名
綠色代表程式中賦予變數的值
很清楚的看出在程式中所使用的 a 就會去取得 001 這個位置中的值(100), 而 b 就是 002 中的 200. 有了這樣的概念, 接下來就是要看看 ActionScript 中 pass by reference 的問題
var a:Number = 100; //定義一個變數 a 併賦予值 100;
function exchangeNumber(i:Number) //定義一個改變變數值的函數
{
i = 200;
}
exchangeNumber(a); //呼叫函數併把 a 函數傳遞過去
trace(a); //輸出 a 目前的值, (100)
對了, 就是這個部份, 在執行到函數的時候 i 應該相等於 a 了啊, 此時更改 i 的話也就等於改變 a, 但是輸出的結果卻不是 200, 而是 100. 沒錯, 在 C 或 VB 等是會直接改變 a 的值為 200, 但.... 在 Java 的世界中傳遞的不是 reference 而是 value, 也就是說 Java 是 pass by value. 那麼 reference 和 value 的不同處是甚麼?
在上面的記憶體圖片中已經看到了, reference 是指 a 的記憶體位置(紅色), 而 value 指的卻是 a 中的值(綠色). 變數在定義的時候就會創建一塊位置給該變數, 之後賦予的值會根據這個指定的位置而填入. 那麼在 C 的時候 exchangeNumber(a) 所傳遞到函數的就是 001 這個位置的編號, 所以 i 賦予 200 時就會根據所提供的位置把當中的值進行更改. 但在 Java 傳遞過去的是記憶體中的值, 那麼 i 在被賦予 200 的時候不知道要根據哪個位置去進行更改就造成維持不變的原因了.
說到這裡有經驗的編程員會問, 為何 Object 卻可以改變當中的變數值, 如:
var obj:Object = new Object();
obj.a = 100;
function changeNumber(o:Object) {
o.a = 200;
}
changeNumber(obj);
trace(obj.a); //輸出得 200
舉個例子來說, 假設記憶體位置空間是個書架, 那麼書架的每層都可以存放屬於自己的空間, 也就是圖片中的這個形式
這圖中顯示著 a 是 obj 中的成員, 所以記憶體位置已經記錄在 obj 的值當中, 那也就是為甚麼 o.a 能夠找到記憶體的位置併賦予新的值. 以下是另一個驗證
var obj1:Object = new Object();
obj1.a = 10;
var obj2:Object = new Object();
obj2.a = 100;
function swapObj2(c:Object, d:Object) {
c.a = 200; //賦予 c 值中 a 位置
var temp:Object = c; //把 c 值賦予到 temp 記憶體位置中
trace("temp.a = "+temp.a); //此刻 temp.a 和 c.a 是同時指向同一個記憶體位置, 所以更動 temp.a 那麼 c.a 的值也會跟著變動
c = d; //把 d 值賦予 c 值, 但因為沒傳遞 c 的記憶體位置, 所以 c 無法改變內容值
temp.a = 1; //賦予 temp 中 a 記憶體位置
d = temp; //理論同上
}
swapObj2(obj1, obj2);
trace("obj1.a = "+obj1.a+", obj2.a = "+obj2.a);
到這裡那些不明白原因的朋友應該抓到重點了吧, 只要多思考和多運用一下大家就可以熟悉了
[ 本帖最后由 Super-Tomato 于 2008-10-17 02:17 AM 编辑 ] |
-
总评分: 积分 + 5
查看全部评分
|