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这种类型了,一旦使用这个类型,数据将永远存在。

基于程序的上下文,大多数时候这样的选择是默认的,我们可以通过指定关键字storagememory修改它。

默认的函数参数,包括返回的参数,他们是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的新长度。






猜你喜欢

转载自blog.csdn.net/aaa19890808/article/details/79335233