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

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

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

一、定长的字节数组

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中是否包含某个key,因为它认为每⼀个都存在,不存在的返回0或false。映射可以被视作为⼀个哈希表,在映射表中,不存储键的数据,仅仅存储它的 keccak256 哈希值,⽤来查找值时使⽤。映射类型,仅能⽤来定义状态变量,或者是在内部函数中作为storage类型的引⽤。不⽀持lengthkey不⽀持string 类型
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;
    // }
    
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/1323518.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存