delete操作
简介:
区块链做为一种公用资源,为避免大家滥用。且鼓励主动对空间的回收,释放空间将会返还一些gas。
但是这里的delete跟其他语言的delete有区别
分别说明:
1、bool
delete后,对应变量被清为false;
pragma solidity ^0.4.0;
contract delete_test{
function delete_f() returns(bool) {
bool b=true;
delete b;
return b;
}
}
2、uint
delete后,对应变量被清为0;
3、 address类型
delete后,对应变量被清为0x00;
delete前:
delete后:
4、bytes
delete后,对应变量为0x00;
测试代码:
pragma solidity ^0.4.0; //delete前
contract delete_test{
function delete_f() returns(bytes) {
bytes memory varBy = "123";//0x0
//delete addr;
return varBy;
}
}
pragma solidity ^0.4.0; //delete后
contract delete_test{
function delete_f() returns(bytes) {
bytes memory varBy = "123";//0x0
delete addr;
return varBy;
}
}
delete前:
delete后:
5、string
delete后,对应变量变为空字符串
pragma solidity ^0.4.0;
contract delete_test{
function delete_f() returns(string) {
string memory str = "hello world!";//""
delete str;
return str;
}
}
delete后:
6、枚举类型
delete后,对应实例变为0,即为定义时的第一个元素
测试代码:
pragma solidity ^0.4.0;
contract delete_test{
enum Light{RED, GREEN, YELLOW}
Light light;
function delete_f() returns(Light) {
light = Light.YELLOW;
delete light;
return light;
}
}
delete结果:
7、 结构体
delete结构体变量,将结构体所有变量重置【根据上面的bool、uint、、、等】
测试代码:
pragma solidity ^0.4.0;
contract delete_test{
struct S{
uint a;
string b;
bytes c;
}
S s;
function delete_f() returns(uint, string, bytes) {
s = S(10, "Hello world!", "abc");
//删除结构体将重置所有元素
delete s;
return (s.a, s.b, s.c);
}
}
delete后结果:
8、 映射
映射是一个特殊的存在,由于映射的键并不总是能有效遍历(数据结构没有提供接口,也并不总是需要关心所有键是什么),所存的键的数量往往是非常大的,所以我们并不能直接删除一个映射。
但我们可以指定键来删除映射中的某一项:
测试代码:
pragma solidity ^0.4.0;
contract delete_test{
mapping(address => uint) stateVar;
function delete_f() returns(uint) {
stateVar[msg.sender]=123;
delete stateVar[msg.sender];
return stateVar[msg.sender];
}
}
delete结果:
9、 定长数组
delete操作后,将数组内所有元素置为初值(0)。
测试代码:
pragma solidity ^0.4.0;
contract delete_test{
function delete_f() returns(uint) {
uint[3] memory array=[uint(3),2,1];
delete array;
return array[0];
}
}
delete结果:
10、变长数组
delete变长数组,会将变长数组长度置0,数组原来的元素不能再访问
测试代码:
pragma solidity ^0.4.0;
contract delete_test{
function delete_f() returns(uint) {
uint[] memory a = new uint[](7);
a[0] = 100;
a[1] = 200;
delete a;
return (a[0]);
}
}
调用函数时会报错,原因是不能再访问元素:
那么,返回一下数组长度 ,将上述代码最后一行的 return (a[0]); 改为 a.length
再调试:【可见,数组长度变为0】
11、删除数组的一个元素
与delete一个uint类似,只是将值变为初始0
delete与gas的考虑:
清理空间,可以获得gas的返还。但无特别意义的数组的整理和删除,只会消耗更多gas,需要在业务实现上进行权衡。
因为delete操作本身也是要消耗gas的,由于gas的限制,因此删除数组其中一个元素并不会调整整个数组。
实例:
利用复用来代替delete
- 当已有的数组不需再使用
- 而要新建一个数组时
- 可以用复用的办法,即新数组覆盖原数组
uint numElements = 0;
uint[] array;
function insert(uint value) {//数组元素插入、覆盖函数
if(numElements == array.length) {
array.length += 1;
}
array[numElements++] = value;
}
function clear() {
numElements = 0; //需要覆盖原数组,则执行这个函数
}