【以太坊开发-03】Solidity基础语法(中)

上期主要介绍了一些数据类型,这期继续详细介绍数据类型的使用

一、定长的字节数组

solidity内置了⼀些数组的数据类型:

  • bytes1 , … , bytes32 ,允许值以步⻓1递增。
  • byte默认表示bytes1,byte是类型,bytes是类型,bytes1是内置数组
  • bytes1只能存储1个字节,即8位的内容,bytes2最多只能存储2个字节,即16位的内容。以此类推…
  • 读取⻓度 length
  • ⻓度不可以修改
  • 可以通过下标访问
  • 内容不可修改
pragma solidity ^0.4.2;
//bytes1
contract fixedArray {
    
    
 
 /*
 1. ⻓度可以读取 length
 2. ⻓度不可以修改
 3. 可以通过下标访问
 4. 内容不可修改 
 */
 //bytes1 ... bytes32
 
 //bytes1 b1 = "xy";
 bytes2 b2 = "xy";
 
 bytes3 public b3 = "xy";
 
 uint public len = b3.length;
 
 //b3.length = 10;
 
 bytes8 b8 = "12345678";
 
 //b8_0返回0x31,即⼗进制的数字1的ascii值(3*16+1=49)
 bytes1 public b8_0 = b8[0];
 
 //b = "HELLO";ERROR,定义之后不可修改
 //b8[1] = "0";
 //b8= "4567";
}

动态大小的字节数组

bytes : 动态⻓度的字节数组(⾮值类型)
string : 动态⻓度的UTF-8编码的字符类型(⾮值类型)

⼀个好的使⽤原则是: bytes⽤来存储任意⻓度的字节数据,string⽤来存储任意⻓度的UTF-8编码 的
字符串数据。 如果⻓度可以确定,尽量使⽤定⻓的如byte1到byte32中的⼀个,因为这样更省空间。

bytes动态字节数组

  • 可以不分空间,直接进行字符串赋值,会自动分配空间
  • 如果未分配过空间,使用下标访问会访问越界报错
  • 可以设置长度,自动分配对应空间,并且初始化为0
  • 可以通过下标进行数据修改
  • 支持push操作,在bytes最后面追加元素
pragma solidity ^0.4.24;


contract  Test {
    
    

    bytes public name;
    
    
    function getLen() public view returns(uint256) {
    
    
        return name.length;
    }

    //1. 可以不分空间,直接进行字符串赋值,会自动分配空间
    function setValue(bytes input) public {
    
    
        name = input;
    }
    
    //2. 如果未分配过空间,使用下标访问会访问越界报错
    function getByIndex(uint256 i) public view returns(byte) {
    
    
        return name[i];
    }
    
    //3. 可以设置长度,自动分配对应空间,并且初始化为0
    function setLen(uint256 len) public {
    
    
        name.length = len;
    }
    
    
    //4.可以通过下标进行数据修改
    function setValue2(uint256 i) public {
    
    
        name[i] = 'h';
    } 
    
    //5. 支持push操作,在bytes最后面追加元素
    function pushData() public {
    
    
        name.push('h');
    } 
}

字符串string

  • 动态尺寸的UTF-8编码字符串,是特殊的可变字节数组
  • 引用类型
  • 不支持下标索引
  • 不支持length、push方法
  • 可以修改(需通过bytes转换)
pragma solidity ^0.4.24;


contract  Test {
    
    

    string public name = "lily";
    
    
    function setName() public {
    
    
        bytes(name)[0] = "L";   
    }
    
    function getLength() public view returns(uint256) {
    
    
        return bytes(name).length;
    }
    
    function setLength(uint256 i) public {
    
    
        bytes(name).length = i;
        
        bytes(name)[i - 1] = 'H';
    } 
}

三、转换(byte1/bytes/string)

在这里插入图片描述

pragma solidity ^0.4.24;
contract Test {
    
    
 
 bytes10 b10 = 0x68656c6c6f776f726c64; //helloworld
 //bytes bs10 = b10; //⽆法直接转换
 
 
 bytes public bs10 = new bytes(b10.length);
 
 //1. 固定字节数组转动态字节数组
 function fixedBytesToBytes() public{
    
    
 for (uint i = 0; i< b10.length; i++){
    
    
 bs10[i] = b10[i];
 }
 }
 
 //2.string转动态字节数组
 string greeting = "helloworld";
 bytes public b1;
 function StringToBytes() public {
    
    
 b1 = bytes(greeting);
 }
 
 //3. 动态字节数组转string
 string public str3;
 function BytesToString() public {
    
    
 fixedBytesToBytes();
 str3 = string(bs10);
 }
 //4. fixed bytes to String,error
 function FiexBytesToString(){
    
    
 //string tmp = string(b10);
 }
}

四、数组

内置数组(已介绍)

  • string(不定⻓)
  • bytes(不定⻓)
  • bytes1…bytes32(定⻓)

自定义数组

自定义定长数组

  • 类型T,⻓度K的数组定义为T[K],例如:uint [5] numbers, byte [10] names;
  • 内容可变
  • ⻓度不可变,不⽀持push
  • ⽀持length⽅法
pragma solidity ^0.4.5;
contract test {
    
    
 
 //test1:
 uint[10] value = [1,2,3,4,5];
 uint public sum;
 function getSum(){
    
    
 sum = 0;
 for (uint i = 0; i < value.length; i++){
    
    
 sum += value[i];
 } 
 }
 
 function changeValue(){
    
    
 value[0] = 2; //内容可修改
 //value.length = 100; //报错,⻓度不可修改
 }
 }

不定⻓数组

  • 定义格式为T [ ],例如:string[ ] names, byte[ ] citys。
  • 内容可以修改
  • 可以改变⻓度(仅限storage类型) ⽀持 length 、 push ⽅法
  • memory类型的不定⻓数组不⽀持修改⻓度
pragma solidity ^0.4.24;


contract  Test {
    
    
    
    //第一种创建方式,直接赋值
    uint8[] numbers = [1,2,3,4,5,6,7,8,9,10];
    
    function pushData(uint8 num) public {
    
    
        numbers.push(num);
    }
    
    function getNumbers() public view returns(uint8[]) {
    
    
        return numbers;
    }
    
    
    //使用new关键字进行创建,赋值给storage变量数组
    uint8[] numbers2;
    
    function setNumbers2() public {
    
    
        numbers2 = new uint8[](7);
        numbers2.length = 20;
        numbers2.push(10);
    }
    
    function getNumbers2() public view returns(uint8[]) {
    
    
        return numbers2;
    }
    
    function setNumbers3() public {
    
    
        //使用new创建的memory类型数组,无法改变长度
        //uint8[] memory numbers3 = new uint8[](7);
        uint8[] memory numbers3;
        
        //numbers3.push(10);     
    }
}

五、结构体

pragma solidity ^0.4.5;
contract Test {
    
    
 //定义结构之后⽆分号,与枚举⼀致
 struct Student {
    
    
 string name;
 uint age;
 uint score;
 string sex;
 }
 Student[] public Students;
 
 
 //两种赋值⽅式
 Student public stu1 = Student("lily", 18, 90, "girl");
 Student public stu2 = Student({
    
    name:"Jim", age:20, score:80,
sex:"boy"});
 
 function assign() public {
    
    
 Students.push(stu1);
 Students.push(stu2);
 
 stu1.name = "Lily";
 }
}

六、字典/映射/hash表(mapping)

  • 键key的类型允许除映射外的所有类型,如数组,合约,枚举,结构体,值的类型⽆限制。
  • mapping无法遍历,⽆法判断⼀个mapping中是否包含某个key,因为它认为每⼀个都存在,不存在的返回0或false。
  • 映射可以被视作为⼀个哈希表,在映射表中,不存储键的数据,仅仅存储它的 keccak256 哈希值,⽤来查找值时使⽤。
  • 映射类型,仅能⽤来定义状态变量,不能作为共有函数的参数和返回值。
  • 不⽀持length
  • 声明为public的映射会自动创建一个getter函数,key为参数,value为返回值。
pragma solidity ^0.4.20;


contract Test {
    
    
    //id -> name
    mapping(uint => string) public id_names;
    
    
    
    //构造函数:
    //1. 对象在创建的时候,自动执行的函数,完成对象的初始化工作
    //2. 构造函数仅执行一次
    
    // function Test() public {
    
    
        
    // }

    constructor()  public{
    
    
        id_names[1] = "lily";
        id_names[2] = "Jim";
        id_names[3] = "Lily";
        id_names[3] = "Tom";
    }
    
    function getNameById(uint id)  public returns (string){
    
    
        //加上storage如何赋值?
        string memory name = id_names[id];
        return name;
    }
    
    function setNameById(uint id)  public returns (string){
    
    
        // mapping(uint => string) memory id_name = id_names;
        // var ids = id_names;
        id_names[id] = "Hello";
    }
    
    
    // function getMapLength() public returns (uint){
    
    
    //     return id_names.length;
    // }
    
}

Supongo que te gusta

Origin blog.csdn.net/weixin_42918559/article/details/125083011
Recomendado
Clasificación