02_值类型与引用类型

在这里插入图片描述


博文配套视频:区块链之公有链、联盟链系列课程


值类型与引用类型

Solidity语言特点

  1. 没有main、没有多线程、合约与合约里面的函数都是通过地址调用
  2. 语法简单、类似javascript
  3. 不成熟,但版本更新较快,且兼容性不太好
  4. 具备面向对象特性:封装、继承、多态

数据类型分类

值类型 (值传递)、引用类型 (指针传递, 类似桌面的快捷方式)

值类型包括

  • 布尔值
  • 整型
  • 地址(Address)
  • 定长字节数组
  • 有理数和整型
  • 枚举类型
  • 函数

引用类型

solidity没有指针,是采用storage进行修饰,复杂类型占有较大的空间,在拷贝时占用空间较大。下面这些类型设置为引用

  • 数组 (Array)
  • 结构体
  • 映射

代码演示

值类型演示

pragma solidity >=0.4.0 <0.7.0;  // 声明solidity的版本

// 创建一个智能合约(合约名第一个字母一般大写)
contract SimpleStorage {
    uint _a; // _a,_b 都是值类型
    uint _b; // 创建一个合约变量
    
    // 函数public 访问修饰符,当前合约和其它合约都可以调用此函数
    function setAll(uint i) public {
        _a = _b = i;
    }
    // 修改了_a,_b并没有改变
    function setA(uint a) public {
        _a = a;
    }
    // 返回更新的_a和原来的_b
    function getAB() public view returns (uint,uint) {
        return (_a,_b);
    }
}

测试数据类型类型

// 创建一个智能合约(合约名第一个字母一般大写)
contract SimpleStorage2 {

    uint8 _a;     // 无符号类型, 取值范围是 0~255
    int8 _b;      // 最高位为符号位  -128 ~ 127

    // 超出变量存储范围则调用抛出异常
    function setAll(uint8 a,int8 b) public {
        _a = a;_b = b;
    }
    
    function getAB() public view returns (uint,int) {
        return (_a,_b);
    }
}

引用类型注意事项 (重要)

  1. 值类型没有数据位置的概念,每次赋值时都有独立的副本!
  2. 引用类型包括:数组、结构体,映射、字符串(bytes数组), 只有引用类型才有数据位置的概念
  3. 三种位置,先掌握内存与存储变量
    3.1 内存其生命周期只存在与函数调用期间 --> 函数调用完毕后消失
    3.2 存储: 状态变量 —> 随着合约部署到区块链中(以太坊分布式账本)
    3.3 调用数据 ( 暂时理解成内存变量 略)
  4. 默认的函数参数,包括返回的参数,他们是memory 默认的局部变量是storage。而状态变量只能是

注意:在版本0.5.0之前,数据位置(memory/storage)可以省略,在0.5.0之后需要指定

引用类型之memory测试

pragma solidity >=0.6.1 <0.7.0;

contract RefType {
    
    // 状态变量只能为storage
    string public _name = 'solidity';
    
    // 数据位置相同:memory name --> memory name1 不会创建副本
    function modifyName(string memory name) public pure returns(string memory) {
        string memory name1 = name;  // 指针传递, 修改一个定会影响另一个
        // bytes(name1)[0] = "J";
        // return name;
        bytes(name)[0] = "J";
        return name1;	
    }
    
    function f() public view returns (string memory) {
        // storage _name --> memory name 会创建一个副本
        return modifyName(_name);
    }
}

引用类型之storage测试

contract RefType2 {
	// 状态变量只能为storage
    string public _name = "solidity";

    function f() public{
    	// storage _name --> storage name 不会创建一个副本
        modifyName(_name);
    }

    function modifyName(string storage name) internal{
    	// 修改name1 不会影响到name和_name
        // string memory name1 = name;
        // 修改name1会影响到name和_name
        string storage name1 = name;
        bytes(name1)[0] = 'S';
    }
}

在这里插入图片描述

发布了129 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lsqzedu/article/details/104616708