Solidity基礎(chǔ)教程3——引用類型

本教程使用的開發(fā)環(huán)境是一款在線編譯器——ChainIDE,具體的使用方法在之前的文章當中已經(jīng)有講解過,有需要的同學可以自行查看。

網(wǎng)址:https://eth.chainide.com/

序言

以太坊的EVM就像四十年前的計算機一樣,由于儲存和計算的代價受制于全網(wǎng)的帶寬,需要對每次數(shù)據(jù)拷貝非常謹慎,我們對超過256位的變量(數(shù)組、結(jié)構(gòu)體)儲存往往需要指定它的儲存位置。

同時由于它是一種靜態(tài)語言,每一個變量的類型都必須定義清楚,包括他的儲存位置,不同儲存類型的變量,賦值的方式也是不一樣的。

數(shù)組與結(jié)構(gòu)體

數(shù)組。簡單理解來說可以是由多個相同的值類型構(gòu)成的序列,序列的長度由用戶設(shè)定,或者可以設(shè)定為可變長度。

如果數(shù)組的儲存地址為storage的話,那么值類型可以為任何類型,如果儲存地址為memory,則類型受到ABI類型的限制,不能為address payable、contractenumstruct。

我們通過一些例程來簡單了解一下數(shù)組,包括如何建立數(shù)組與遍歷數(shù)組。

pragma solidity >=0.4.22 <0.6.0;

contract Array{
    //設(shè)定固定長度uint數(shù)組并進行初始化
    uint[5] a = [1,2,3,5,5];      //設(shè)定一個長度為5的uint數(shù)組,名字叫a

    function get_a_value() view public returns(uint)
    {
        return a[1];                       //返回值為2
    }

    bytes9 b = 0x6c690338656363468e;       //定義一個長度為9字節(jié)的值
    byte[] b1;                             //定義一個值類型為byte的變長數(shù)組
    
    //向變長數(shù)組內(nèi)輸出
    function set_b1_array() public returns(byte)
    {
        for (uint i=0;i<=b.length;i++)     //b.length指的是b數(shù)組的長度值
        {
            b1.push(b[i]);          //向數(shù)組b1內(nèi)添加值
        }
        return b[1];                       //返回值為69
    }
}

數(shù)組的定義方式就如上面例程所示,一開始設(shè)定值類型,然后在后面加入一個方括號,方括號內(nèi)是數(shù)組的長度,如果要定義變長數(shù)組則方括號內(nèi)為空,接著加入一個空格,最后是數(shù)組的名字。

uint[5] a;           

數(shù)組類型有個可以調(diào)用的變量叫length,這個變量代表了數(shù)組的長度,可以通過這個變量來對數(shù)組進行遍歷和清空。

變長數(shù)組可以調(diào)用push函數(shù)在數(shù)組的尾部添加值,對于在全局設(shè)定的狀態(tài)變量來說,這種值的修改會使用到很多gas,使用時需慎重。

結(jié)構(gòu)體。結(jié)構(gòu)體就好像一個袋子里有很多的貨物一樣,一個結(jié)構(gòu)體內(nèi)可以包含很多變量,每個變量都是屬于這個結(jié)構(gòu)體的一部分。

結(jié)構(gòu)體的keyword是struct,具體如何定義和調(diào)用可以通過下面的例程進行學習:

   //將結(jié)構(gòu)體設(shè)置為狀態(tài)變量
  uint eth_score = 100;
    Program eth=Program                             //創(chuàng)建一個結(jié)構(gòu)體 名字為eth
        (0x797206393eB6582ac86883fA623CB5A05021191D,
        eth_score,
        100, 
        false);  //在定義結(jié)構(gòu)體時必須將初始化做好,對于賦值為常量的值時,對應的儲存位置為storage
    
    function set_eth_score(uint set_score) public {
        eth.score = set_score;
    }
    
    function get_eth_score() public view returns(uint)
    {
        return eth.score;
    }
  //將結(jié)構(gòu)體設(shè)置為局部變量
    function get_program_param() public pure returns (uint)
    {
        Program memory chainide=Program
        ({contract_address:0x797206393eB6582ac86883fA623CB5A05021191D,
        member_num: 10,
        score:99, 
        capitalize:true});  //在定義結(jié)構(gòu)體時必須將初始化做好,對于賦值為常量的值時,對應的儲存位置為memory
        return(chainide.score);
    }

這個例程分別對將結(jié)構(gòu)體設(shè)置為狀態(tài)變量(storage),以及設(shè)置為局部變量(memory)進行了分別舉例。

Solidity的語言規(guī)范是要在定義結(jié)構(gòu)體時對這個結(jié)構(gòu)體進行初始化,定義初始化有兩種方式,一種是根據(jù)之前定義的結(jié)構(gòu)體順序進行變量的初始化定義,第二種是通過{key:word}的方式進行每個元素的初始化。

tips:通過eth.score的方式可以調(diào)用結(jié)構(gòu)體內(nèi)變量的值,同時也可以根據(jù)之前定義的值類型在returns當中進行設(shè)置,但是要注意的是在現(xiàn)在的solidity當中自定義的結(jié)構(gòu)體類型是不可以作為函數(shù)的返回值。

Storage和memory

在Solidity當中有兩個關(guān)鍵字memory(臨時儲存的變量),storage(永久儲存的變量),這兩個關(guān)鍵字在合約內(nèi)有一些約定俗成的定義,我們可以先通過一個例程來簡單了解一下。

pragma solidity ^0.5.6;
contract Person {

    int public age1;                     //狀態(tài)變量 儲存在storage當中
    string public name1;

    function Person1(int age,string memory name) public{
          age1 = age;                    //局部變量 儲存在memory當中
          name1 = name;
    }

    function Person2 (string memory name3) pure public returns(string memory){       //局部變量  儲存在memory當中
          string memory name2 = name3;
          return (name2);        //局部變量  儲存在memory當中
    }
}

}

通過在編寫程序時,在變量類型和名字的中間加入memory和storage關(guān)鍵字,來對變量的存儲位置進行定義。有些定義是默認的,比如在function作用域以外的變量基本上都是通過storage進行存儲的,而函數(shù)的輸入?yún)?shù)和輸出參數(shù)基本上是memory。

如果函數(shù)當中對儲存位置為storage的變量進行改變,就會需要用到gasfee,因為storage的數(shù)值是存儲在區(qū)塊鏈上的,因此在寫程序時需要盡量減少對儲存類型為storage的變量的賦值。

如果對儲存位置為memory的變量進行賦值和調(diào)用,則是不需要用到gas的,如果函數(shù)內(nèi)都是這種操作,則可以在函數(shù)的()后加上pure定義符,表示這個調(diào)用這個函數(shù)不需要用到gas。

有些更加深入的探索,比如這兩個不同儲存位置的變量之間的相互賦值,會如何影響對方的值,以及這種storage的指針是怎么運行的,在參考資料當中有涉及,有興趣的朋友可以自己點擊查詢。

由于在不同版本的Solidity當中,對于變量的定義和使用的規(guī)則是不一樣的,因此建議大家在編寫程序的時候使用統(tǒng)一的編譯器版本。

今天的教程到這里就結(jié)束了,希望大家有所收獲。

參考資料

Memory和storage的互相轉(zhuǎn)換

狀態(tài)變量與指針傳遞

內(nèi)存與結(jié)構(gòu)體

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 本教程使用的開發(fā)環(huán)境是一款在線編譯器——ChainIDE,具體的使用方法在之前的文章當中已經(jīng)有講解過,有需要的同學...
    prophet__閱讀 696評論 0 0
  • 本教程使用的開發(fā)環(huán)境是一款在線編譯器——ChainIDE,具體的使用方法在之前的文章當中已經(jīng)有講解過,有需要的同學...
    prophet__閱讀 1,406評論 0 0
  • 引用類型 引用類型和值類型相對,在傳遞時,并不拷貝一份新的數(shù)據(jù),而是傳遞是指向同一份數(shù)據(jù)的引用。下面看一個例子: ...
    ObadiObada閱讀 1,307評論 0 1
  • C語言中的類型可分為以下四類,C語言基礎(chǔ)教程之數(shù)據(jù)類型 c中的數(shù)據(jù)類型是指用于聲明不同類型的變量或函數(shù)的擴展系統(tǒng)。...
    C語言基礎(chǔ)閱讀 294評論 0 0
  • solidity的自定義結(jié)構(gòu)體深入詳解結(jié)構(gòu)體,solidity中的自定義類型,我們可以使用關(guān)鍵字struct來進行...
    Lnhj閱讀 1,253評論 0 0

友情鏈接更多精彩內(nèi)容