zoukankan      html  css  js  c++  java
  • 02 基础篇 —引用类型

    2 引用类型

    不定长字节数组(bytes)

    -动态字节数组

    -引用类型(表明可以使用 storage 来修饰,进行引用传递,指针的效果) -支持 下标索引 -支持 length 、 push 方法(push会帮助分配空间的) -可以修改 -以十六进制格式赋值: 'h' -> 0x68 -> 104 -格外注意:对于bytes,如果不使用下标访问,那么可以不用先申请空间, 直接赋值即可,或者 直接push

    代码:

     1 pragma solidity ^0.4.24 ;
     2  3 contract Test{
     4 //动态字节数组,使用new关键字,分配空间
     5 bytes public name=new bytes(32);
     6 bytes public name1;
     7 function setLength(uint _length)public {
     8     name.length=_length;
     9 }
    10 11 function getLength(bytes _name)public pure returns(uint){
    12     return _name.length;
    13 }
    14    function setName(bytes _name)public {
    15        name=_name;
    16        
    17    } 
    18    function changeName(bytes1 _name)public{
    19        name[0]=_name;
    20    }
    21       /*
    22     function changeName1(bytes1 _name)public{
    23         //为未分配空间,访问下表下标错误
    24         name1[0]=_name;
    25     }
    26     */
    27 function pushTest()public{
    28     name1.push("a");
    29 }
    30 function setInside()public{
    31     name="hello";
    32     name1="hello world";
    33 }

     

    字符串(string)

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

    -使用下标索引的话,转成bytes类型

    代码:

     1 pragma solidity ^0.4.24;
     2 contract String{
     3     //引⽤用类型;不支持下标索引;不支持length、push⽅方法;可以修改(需通过bytes转换)
     4     //下表x索引,length都转换成不用bytes来操作
     5     string public name="steven";
     6     function nameBytes()constant returns(bytes){
     7         return bytes(name);
     8     }
     9     function nameLength()constant returns(uint){
    10        //return name.lengh; //z不支持直接使用
    11        return bytes(name).length;
    12     }
    13     function changeName()public{
    14     name="mark";
    15  // name[1}="l";不支持直接索引
    16  bytes(name)[0]="l";
    17 18 }
    19    function changeLength()public{
    20        bytes(name).length=10;
    21    }
    22      

     

    数据位置(Data location)

    复杂类型,不同于之前 值类型 ,占的空间更大,超过256字节,因为拷贝它们占用更多的空间,如数组(arrays) 和 数据结构(struct) ,他们在Solidity中有一个额外的属性,即数据的存储位置: memory 和 storage 。

    ​ - 内存(memory)

    数据不是永久存在的,存放在内存中,越过作用域后无法访问,等待被回收; 被memory修饰的变量是直接拷贝,即与上述的值类型传递方式相同。

    -存储 (storage)

    数据永久保存在。 被storage修饰的变量是引用传递,相当于只传地址,新旧两个变量指向同一片内存空间,效率较高,两个变量有关联,修改一个,另外一个同样被修改; 只有引用类型的变量才可以显示的声明为 storage 。

    • 状态变量量

    状态变量总是stroage类型的,无法更改;

    • 局部变量量

    默认是storage类型(仅限数据结构或数组,string),但是可以声明为memory类型。

    -对于非值的数据类型,比如数组和结构体,赋值的语法比较复杂:

    .赋值给一个状态变量总是创建一个完全无关的拷贝

    .赋值给一个局部变量,仅对基本类型,如那些32字节以内的(静态类型(static types)),创建一份完全无关的拷贝;

    .如果是数据结构或数组,(包括bytes和string)类型,由状态变量赋值为一个局部变量,局部变量只是持有原始状态变量的一个引用。对于这个局部变量再次赋值,并不会修改这个状态变量,只是修改了引用(局部变量指向了别人);但是修改这个本地引用变量(局部变量)的成员值,会改变状态变量的值(修改了所引用的状态变量值)localTest()的测试

    代码:

     

     1 pragma solidity ^0.4.24;
     2  3 contract test2{
     4    //memory:存放在内存中,不是永久存在,超越于作用域后,等待被回收;志值传递
     5     //storage:数据永久保存,引用传递传递,c效率高
     6     //状态变量变量总是storage类型;局部变量是storage(仅限数据结构或数组,string),但是可以memory
     7 string public name= 'lily';
     8 uint256 public num = 10;
     9 10 function call1() public {
    11     setName1(name);
    12 }
    13 //对于引用数据类型,作为函数参数时 默认是memory类型(值传递)
    14 function setName1(string src) private {
    15 //function setName1(string memory src) private {
    16     num = 100; //num变为100
    17     bytes(src)[0] = "L";//name还是小写
    18 }
    19 function call2() public {
    20     setName2(name);
    21 }
    22     
    23 //如果想引用传递,需要显示指明storage
    24 function setName2(string storage src) private {
    25         num = 1000;//num为1000
    26         bytes(src)[0] = "L";//name变成大写
    27     }
    28     
    29 //如果局部变量是string,数组,结构体类型数据,默认是storage类型    
    30  function localTest () public {
    31     string memory tmp = name;
    32     bytes(tmp)[0] = "L";//name变大写
    33 } 
    34
    View Code

    转换(byte1/bytes/string)

     1 pragma solidity ^0.4.24;
     2 contract Transformation{
     3     //(byte1/bytes/string)相互转换
     4     
     5      bytes10 b10 = 0x68656c6c6f776f726c64;     //helloworld
     6     //bytes bs10 = b10; //⽆无法直接转换
     7     
     8   
     9     bytes public bs10 = new bytes(b10.length);
    10     
    11     //1. 固定字节数组转动态字节数组;需要逐一赋值
    12     function fixedBytesToBytes() public{
    13         for (uint i = 0; i< b10.length; i++){
    14             bs10[i] = b10[i];
    15         }
    16     }
    17     //2.string转动态字节数组
    18     string  greeting = "helloworld";
    19     bytes public b1;
    20     function StringToBytes() public {
    21         b1 = bytes(greeting);
    22     }
    23     //3. 动态字节数组转string
    24     string public str3;
    25     function BytesToString() public {
    26         fixedBytesToBytes();
    27         str3 = string(bs10);
    28     }
    29      function FiexBytesToString(){
    30      //固定字节数组和string无法转换
    31         //string tmp = string(b10);
    32     }
    33     
    34 }
    View Code

    数组

    -内置数组:string(不定长)、bytes(不定长)、byte1,byte2...(定长);

    -自定义数组:

    类型T,长度K的数组定义为T[K],例如:uint [5] numbers, byte [10] names; 内容可变; 长度不可变,不支持push; 支持length方法。

    -不定长数组:

    定义格式为T [ ],例例如:string[ ] names, byte[ ] citys; 内容可以修改; 可以改变长度(仅限storage类型) 支持 length 、 push 方法; memory类型的不定长数组不支持修改长度;

     1 pragma solidity ^0.4.24;
     2 contract C {
     3     /*
     4     定长数组
     5     */
     6      uint[10] value = [1,2,3,4,5];
     7      uint public sum;
     8      
     9     function getSum()public returns(uint ){
    10        sum=0;
    11         for (uint i = 0; i < value.length; i++){
    12             sum += value[i];
    13             
    14         } 
    15         return sum ;
    16     }
    17     function changeValue(){
    18         value[0] = 2; //内容可修改
    19         //value.length = 100; //报错,长度不可修改
    20     }    
    21     
    22     //test2:
    23     //helloworld : 0x68656c6c6f776f726c64
    24     bytes10 helloworldFixed = 0x68656c6c6f776f726c64;
    25     byte [10] helloworldDynamic = [byte(0x68), 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64];
    26     bytes helloworld;
    27     
    28     function changeByte() public {
    29         //helloworldFixed[0] = 0x69; //error
    30         helloworldDynamic[0] = 0x69; //ok
    31     }
    32     
    33   function getString () public constant returns (string) {
    34     for (var i = 0; i < helloworldDynamic.length; i++) {
    35      helloworld.push(helloworldDynamic[i]);//不定长字节数组,没有开辟空间,可以直接赋值或者push 
    36         }
    37         
    38         return string(helloworld);
    39     }
    40
    View Code

    结构体

     1 pragma solidity ^0.4.24;
     2 contract StructType{
     3      //定义结构之后无分号,与枚举⼀致
     4     struct Student{
     5         string name;
     6         uint age;
     7         uint score;
     8         string sex;
     9     }
    10     Student []public Students;//定义结构体数组
    11     //看两种赋值方式
    12     Student public stu1=Student("steven",18,99,"m");
    13     Student public stu2=Student({name:"mark",age:19,score:90,sex:"w"});
    14     function assign()public{
    15         Students.push(stu1);
    16         Students.push(stu2);
    17         stu1.name="lily";
    18     
    19     }
    20 }

    字典/映射/哈希(mapping)

    -键key的类型允许除映射外的所有类型,如数组,合约,枚举,结构体,值的类型无限制; -无法判断一个mapping中是否包含某个key,因为它认为每一个都存在,不存在的返回0或false; -映射可以被视作为一个哈希表,在映射表中,不存储键的数据,仅存储它的 keccak256 哈希值,用来查找值时使用; -映射类型,仅能用来定义状态变量,或者是在内部函数中作为storage类型的引用。 -不支持length -key不支持string 类型​

     1 pragma solidity ^0.4.24;
     2  3 contract test{
     4     //id->name
     5     mapping(uint=>string)id_name;
     6     constructor ()public{
     7         //构造函数
     8         id_name[0x01]="steven";
     9         id_name[0x02]="lily";
    10         id_name[0x03]="mark";
    11 }
    12 function getNameById(uint id)public view returns(string){
    13     string memory name=id_name[id];
    14     return name;
    15     }
    16 }

    引用类型之间的比较

    每天的价值就是不停息的前进!!!
  • 相关阅读:
    Ztree下拉框多选
    FullCalendar日程插件
    viscose 前端常用插件
    一些词
    关于require()和export引入依赖的区别
    关于CMD/AMD和Common.js/Sea.js/Require.js
    vue中的双向数据绑定原理简单理解
    Vue-cli简单使用
    webpack简单配置
    vuex基础
  • 原文地址:https://www.cnblogs.com/zhaopp/p/11970360.html
Copyright © 2011-2022 走看看