網頁

2011/08/21

ActionScript中的傳值與傳址

今天在看DS發現了一個滿有趣的問題,要怎麼使用ActionSript使用傳址的而不是傳值到函數之中。會這麼想是因為如果使用c語言可以使用指標,但是在as中並沒有這樣功能。

Consider the as function:
var a:int = 1;
var b:int = 2;
swap(a,b);
trace("a:" + a + ",b:" + b); //a:1,b:2

public function swap(num1:int,num2:int):void {
   var temp:int = num1;
   num1 = num2;
   num2 = temp;
}

trace出來會變成「a:1,b:2」,因為是將值丟到swap這個function時,會將a、b複製一個複本給swap的num1,num2,而不是原來的a、b,這樣稱之為「傳值」。如果是c語言就可以直接傳址進去,直接將a、b兩個變數直接交換,由於是直接指向記憶體,稱之為「傳址」。

但在as之中要怎麼辨到傳址的功能呢?它並沒有像c一樣的語法「*、&」可以使用,於是查找了官方文件找到「函數參數」,原來可以包裝成物件,在as中物件是以傳址的方式進行的。

Instead of the code:
var num:Object = {a:1,b:2};
swap2(num);
trace("a:" + num.a + ",b:" + num.b); //a:2,b:1

public function swap2(num:Object):void{
   var temp:int = num.a;
   num.a = num.b;
   num.b = temp;
}

噢,太好啦,終於達到我想要的效果了,可以將兩個變數交換過來了。使用傳址的好處之一是記憶體會較省空間,因為不需要在copy另外一個複本給function(當然區域變數使用完會釋放掉),如此推斷在執行的速度也會比較快,少掉了複製複本的時間。這讓我想到在OOP的撰寫時通常會寫一個Value Object(VO)來描述一個物件的Data Structure,除了可以將資訊做一個整理外,在傳輸時也可以用傳址的方式來處理,這也算是另外一個好處之一吧。

結論:
.自訂類別、物件是使用傳址而非傳值。
.基本物件型別(Boolean、Number、int、uint、String)為傳值而非傳址
.使用傳址會較省記憶體空間,且速度較快
.Array是物件,所以也是傳址

沒有留言: