1. 程式人生 > >Solidity基礎入門知識(四)列舉、儲存型別和陣列

Solidity基礎入門知識(四)列舉、儲存型別和陣列

今天米切爾致敬卡特轉身成功問鼎扣籃王,可惜只有形而無神,就連形都差點意思--!

列舉型別一個變數可能的取值都知道,就可以把它定義為列舉型,然後把變數的值一一列出來,令變數的值只限於列舉出來的值的範圍內。例如月份、星期幾、天氣等情況,列舉型別用enum關鍵字來定義。

例子:enum weekday{sun,mon,tue,wed,the,fri,sat};

上面聲明瞭一個列舉型別weekday,花括號中的sun mon等稱為列舉元素,weekday的值只能是括號內的七個值。

在程式中可以用weekday.sun這種格式來引用列舉型別的值。列舉元素的值在沒有指定的情況下,第一個預設為0,往後的自增一,例如sun=0,mon=1,tue=2。有指定值的時候就用指定值,其後元素如果沒有指定則自增一。

資料位置(儲存型別)複雜型別,如陣列(arrays)資料結構(struct)在Solidity中有一個額外的屬性,資料的儲存位置,等同於資料的儲存方式,臨時還是永久。可選為memory(臨時)storage(永久)

memory儲存位置同我們普通程式的記憶體一致。即分配,即使用,越過作用域即不可被訪問,等待被回收。而在區塊鏈上,由於底層實現了圖靈完備,故而會有非常多的狀態需要永久記錄下來。比如,參與眾籌的所有參與者,參與投票的所有人員。那麼我們就要使用storage這種型別了,一旦使用這個型別,資料將永遠存在。

基於程式的上下文,大多數時候這樣的選擇是預設的,我們可以通過指定關鍵字storage

memory修改它。

預設的函式引數,包括返回的引數,他們是memory。預設的區域性變數是storage的。而預設的狀態變數(合約宣告的公有變數)是storage

另外還有第三個儲存位置calldata。它儲存的是函式引數,是隻讀的,不會永久儲存的一個數據位置。外部函式的引數(不包括返回引數)被強制指定為calldata。效果與memory差不多。

資料位置指定非常重要,因為不同資料位置變數賦值產生的結果也不同。在memorystorage之間,以及它們和狀態變數(即便從另一個狀態變數)中相互賦值,總是會建立一個完全不相關的拷貝。(這句話沒看懂,再議!)

將一個storage的狀態變數,賦值給一個storage

的區域性變數,是通過引用傳遞。所以對於區域性變數的修改,同時修改關聯的狀態變數。但另一方面,將一個memory的引用型別賦值給另一個memory的引用,不會建立另一個拷貝。(再議,——!)

陣列(arrays):一個型別為uint,元素個數為5的陣列x應該這樣定義:uint[5] x,而一個元素個數可變的陣列應該定義為:uint[ ] x。定義多維陣列:uint [5][4] x,表示二維陣列x包含四個陣列,每個陣列有五個元素。uint[ ][4],表示包含四個陣列,每個數組裡的元素個數可變。需要注意的是,相比python等語言,多維陣列的元素個數宣告是相反的。x[2][1],這個表示訪問第三個數組裡的第二個元素,這裡的順序是正常順序(--!)。

型別為陣列的狀態變數,可以標記為public(公共)型別,從而讓solidity建立一個訪問器(再議)。

陣列有一個length屬性,表示當前的陣列長度(即一維陣列的元素數量,二維數組裡一維陣列的數量)。storage型別的變長陣列可以通過給length賦值來改變陣列的長度,但memory型別(例如用new關鍵字建立的陣列)的陣列不支援這個功能,但可以通過調整引數的方法來改變長度。

例子:

contract C {
    function f() {
        //建立一個memory的陣列
        uint[] memory a = new uint[](7);
        
        //不能修改長度
        //Error: Expression has to be an lvalue.
        //a.length = 100;
    }
    
    //storage
    uint[] b;
    
    function g(){
        b = new uint[](7);
        //可以修改storage的陣列
        b.length = 10;
        b[9] = 100;
    }
}

可以看出來,storage型別的可以通過賦值length來更改長度,但memory型別的不行。

push方法:storage的變長陣列和bytes陣列都有一個push方法,用於新增新元素到陣列末端,返回值為新的長度。

例子:a=[1,2,3]   a.push(4)意為將元素4新增到陣列a中,新的a為[1,2,3,4],並返回陣列a的新長度。