博文配套视频:区块链之公有链、联盟链系列课程
值类型与引用类型
Solidity语言特点
- 没有main、没有多线程、合约与合约里面的函数都是通过地址调用
- 语法简单、类似javascript
- 不成熟,但版本更新较快,且兼容性不太好
- 具备面向对象特性:封装、继承、多态
数据类型分类
值类型 (值传递)、引用类型 (指针传递, 类似桌面的快捷方式)
值类型包括
- 布尔值
- 整型
- 地址(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);
}
}
引用类型注意事项 (重点)
- 值类型没有数据位置的概念,每次赋值时都有独立的副本!
- 引用类型包括:数组、结构体,映射、字符串(bytes数组), 只有引用类型才有数据位置的概念
- 三种位置,先掌握内存与存储变量
3.1 内存其生命周期只存在与函数调用期间 --> 函数调用完毕后消失
3.2 存储: 状态变量 —> 随着合约部署到区块链中(以太坊分布式账本)
3.3 调用数据 ( 暂时理解成内存变量 略) - 默认的函数参数,包括返回的参数,他们是memory 默认的局部变量是storage。而状态变量只能是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';
}
}