solidity 基本語法 - 引用類型

引用類型

引用類型和值類型相對,在傳遞時具钥,并不拷貝一份新的數(shù)據(jù)氓拼,而是傳遞是指向同一份數(shù)據(jù)的引用桃漾。下面看一個例子:

pragma solidity ^0.4.23;

contract RefTypeTest {   
    event PrintValue(uint value1, uint value2);
    function testRefType() public {
        uint[] x;
        x.push(1);
        x.push(2);
        x.push(3);
        uint[] y = x;
        emit PrintValue( x[0],  y[0]);
        y[0] = 0;
        emit PrintValue( x[0],  y[0]);  
    }
}

上述代碼輸出的結(jié)果為:

[
    {
        "event": "PrintValue",
        "args": {
            "0": "1",
            "1": "1",
            "value1": "1",
            "value2": "1",
            "length": 2
        }
    },
    {
        "event": "PrintValue",
        "args": {
            "0": "0",
            "1": "0",
            "value1": "0",
            "value2": "0",
            "length": 2
        }
    }
]

從結(jié)果中可以看出撬统,x 和y 指向了同一份數(shù)據(jù)恋追。solidity中的引用類型包括苦囱,動態(tài)數(shù)組和結(jié)構(gòu)體兩種撕彤。

存儲位置

solidity中對于復雜的類型(array羹铅,struct)有一個額外的概念用于定義變量(成員)的存儲位置职员。solidity 中存儲位置分別有memorystoragecalldata. storage是持久化的存儲倒谷,memorycalldata類似是非持久化的存儲渤愁。

對于不同的類型變量诺苹,都擁有一個默認的存儲位置,可以通過memory或是storage關(guān)鍵字改變掌呜。對于某些類型的變量质蕉,solidity會使用一個強制的存儲位置模暗,具體的規(guī)則如下:

  • Forced data location:
    • parameters (not return) of external functions: calldata
    • state variables: storage
  • Default data location:
    • parameters (also return) of functions: memory
    • all other local variables: storage

復雜類型

動態(tài)數(shù)組(Arrays)

動態(tài)數(shù)組是指在運行期間確定元素個數(shù)的為主,solidity中的格式為:

T[] array;

動態(tài)數(shù)組有兩個成員:

  • push 向數(shù)組追加元素
  • length 獲得數(shù)組中元素的個數(shù)

對于存儲在memory中的動態(tài)數(shù)組隶糕,push方法將無法使用枚驻,這是由于EVM(solidity虛擬機)在組織不同位置的數(shù)據(jù)采用了不同的數(shù)據(jù)結(jié)構(gòu)導致测秸,后續(xù)post會詳細介紹這些數(shù)據(jù)結(jié)構(gòu)铃拇。

  byte[] storageArray;
  
 function pushToArray(byte value) public {
     storageArray.push(value);
     byte[] memory memoryArray = new byte[](15);
     // memoryArray.push(value); compile error
 }

bytes 和 string是兩種特殊的數(shù)組慷荔,bytes 和 byte[]類似贷岸,string 是特殊的bytes類型偿警,但是無法訪問push 和length元素螟蒸。

結(jié)構(gòu)體(struct)

struct 是solidity中用于定義新的數(shù)據(jù)結(jié)構(gòu)的方法七嫌,其語法和c語言中的結(jié)構(gòu)體類似诵原。

struct Operation {
        bytes31 hash;
        uint8 status;
}

Operation[] operations;
function addOperation(bytes31 opHash,  uint8 status) public {
     Operation memory op;
     op.hash = opHash;
     op.status = status;
     operations.push(op);
}

存儲位置對復雜類型的影響

復雜類型存儲在不同位置的變量蔓纠,相互賦值的行為會有差異贺纲,下面通過一個例子來介紹:

pragma solidity ^0.4.23;

contract Contract{
    uint[] x; // the data location is storage
    uint[] y; // the data location is storage

    event PrintUint(uint value1, uint value2);

    // Test memory assigin to storage
    function m2s(uint[] memoryArray) public {
        x = memoryArray; // works, copies the whole array to storage
        x[0] = 1;
        emit PrintUint(x[0], memoryArray[0]);
    }

    // Test assigin storage to storage
    function s2s() public {
        x[0] = 0;
        y = x;
        y[0] = 1;
        emit PrintUint(x[0], y[0]);
    }
    
    // Test assigin storage to memory
    function s2m() public {
        y[0] = 0;
        uint[] memory memoryArray = y;
        memoryArray[0] = 1;
        emit PrintUint(memoryArray[0], y[0]);
    }
    
    // Test memoryArray assigin to memoryArray
    function m2m(uint[] memoryArray) public {
        // default local variable is in storage
        // uint[] memoryArray1 = memoryArray;
        uint[] memory memoryArray1 = memoryArray;
        memoryArray1[0] = 1;
        emit PrintUint(memoryArray[0], memoryArray1[0]);
    }
}

分別測試上述四個函數(shù),結(jié)果如下:

  • m2s
[
    {
        "event": "PrintUint",
        "args": {
            "0": "1",
            "1": "0",
            "value1": "1",
            "value2": "0",
            "length": 2
        }
    }
]
  • m2m
    輸入 [0]
    輸出:
[
    {
        "event": "PrintUint",
        "args": {
            "0": "1",
            "1": "1",
            "value1": "1",
            "value2": "1",
            "length": 2
        }
    }
]
  • s2m
[
    {
        "event": "PrintUint",
        "args": {
            "0": "1",
            "1": "0",
            "value1": "1",
            "value2": "0",
            "length": 2
        }
    }
]
  • s2s
[
    {
        "event": "PrintUint",
        "args": {
            "0": "0",
            "1": "1",
            "value1": "0",
            "value2": "1",
            "length": 2
        }
    }
]

從上面的輸出結(jié)果可以看出,對于存儲在不同位置的復雜類型澄成,賦值操作的表現(xiàn)會有所不同墨状,總結(jié)如下:

  • storage to storage 拷貝數(shù)據(jù), 表現(xiàn)為值類型

  • storage to memory 拷貝數(shù)據(jù),表現(xiàn)為值類型

  • memory to storage 拷貝數(shù)據(jù)镐确,表現(xiàn)為值類型

  • memory to memory 拷貝引用源葫,表現(xiàn)為引用類型

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市芭届,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌即硼,老刑警劉巖只酥,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绝编,居然都是意外死亡十饥,警方通過查閱死者的電腦和手機逗堵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來作媚,“玉大人掂骏,你說我怎么就攤上這事∶昂冢” “怎么了抡爹?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵欧穴,是天一觀的道長涮帘。 經(jīng)常有香客問我调缨,道長弦叶,這世上最難降的妖魔是什么伤哺? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮桃序,結(jié)果婚禮上媒熊,老公的妹妹穿的比我還像新娘芦鳍。我一直安慰自己柠衅,他們只是感情好菲宴,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谣蠢,像睡著了一般挤忙。 火紅的嫁衣襯著肌膚如雪册烈。 梳的紋絲不亂的頭發(fā)上茄厘,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音吆录,去河邊找鬼哀卫。 笑死此改,一個胖子當著我的面吹牛共啃,可吹牛的內(nèi)容都是我干的移剪。 我是一名探鬼主播纵苛,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悬槽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乔宿,沒想到半個月后详瑞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坝橡,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赖阻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片火欧。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡离陶,死狀恐怖招刨,靈堂內(nèi)的尸體忽然破棺而出沉眶,到底是詐尸還是另有隱情谎倔,我是刑警寧澤片习,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布状知,位于F島的核電站饥悴,受9級特大地震影響西设,放射性物質(zhì)發(fā)生泄漏贷揽。R本人自食惡果不足惜擒滑,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淹冰。 院中可真熱鬧樱拴,春花似錦晶乔、人聲如沸正罢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽运提。三九已至,卻和暖如春诫咱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背签钩。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留莽鸿,地道東北人祥得。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓乒疏,卻偏偏與公主長得像怕吴,于是被迫代替她去往敵國和親转绷。 傳聞我的和親對象是個殘疾皇子议经,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容