solidity 以太坊智能合约语言(五)

对数据结构的进一步深入理解

1、数据位置

变量的存储位置有三种:memory, storage和calldata。calldata比较特殊,一般只有外部函数的参数被强制指定为这种类型。memory存在EVM的内存中,storage将会被存放在链中block。

函数参数的默认位置是memory,状态变量是storage。

2、数据位置的相互转换

2.1 storage转storage时,只是修改了指针。

2.2 memory转storage时,将内存变量拷贝到存储中。

pragma solidity ^0.4.0;

contract MemoryConvertToStateVariable{

  struct S{string a;
           uint b;}

  //default storage
  S s;

  function memoryToState(S memory tmp) internal{
    s = tmp;//从内存中复制到状态变量中。

    //修改旧memory中的值,并不会影响状态变量
    tmp.a = "Test";
  }

}

2.3 storage 转memory,将实际数据拷贝到内存

2.4 memory转memory,由于是引用传递,并不会拷贝数据

3、数组

可以使用字面量隐式创建一个定长数组,也可以用new关键字初始化一个数组。

// 字面量隐式创建
uint[3] arrays = [1,2,3];
// 关键字new创建
uint[] sra = new uint[2];

数组的属性:length。对于storage的变长数组,可以用length复制调整数组的长度。

// 长度为1的storage数组
uint[] state = new uint[1];

function autoIncrease(uint a) returns(uint){
    state[state.length++] = a;
    return state[state.length-1];
}

push属性:变长的storage数组和bytes有一个push方法,添加一个新元素到数组末端。

多维数组:在外部函数中,不能使用多维数组。

bytes和string:bytes类似于byte[],但是在外部函数使用过程中,会被优化压缩,更节省空间。string类似bytes,但是不提供长度和下标访问。bytes和string可以互相转换。

对于外部函数不能使用变长数组,可以使用一个非常大的定长数组[];

4、结构体

结构体中除了不能包含自身定义的结构外,其他类型都能包含,也不能是无限大小。

结构体的初始化分为:按顺序填值,可以跳过映射类型。命名初始化。

结构体目前是internal,所以只能在当前合约或者合约的继承类中使用。目前,由于结构体是动态内容,不支持合约间的相互用。

5、映射类型

映射是一种引用类型,存储键值对,但是有以下特点:

5.1 只能是状态变量。

     由于映射中键的数量数动态的,映射的大小也是动态的,只能声明为storage,或者赋值给一个storage的对象引用。映射的键是除映射、变长数组、合约、枚举、结构体外的任意类型,值是任意类型。

     映射因为存储在链上,存储的值是可以动态更改的,存储模型是以hash键值对的方式,

 

你可能感兴趣的:(区块链——智能合约)