1.memory与storage的区别
- 函数外部声明的变量默认储存在storage里(全局变量)
- 函数内部声明的变量默认储存在memory里(局部变量)
pragma solidity ^0.4.0;
// Storage变量是指永久存储在区块链中的变量
// Memory 变量是临时的,当外部函数对某合约调用完成时,内存型变量即被移除
// 内存(memory)位置还包含2种类型的存储数据位置,一种是calldata,一种是栈(stack)
contract memoryTest{
// storage(区块链)和memory(内存)的最大区别:storage在区块链中是永久保存的数据,类似一部分全局变量
// 而memory在内存中产生,也同时随着内存销毁,不是永久保存的
uint public num1 = 5;
// 以下变量中的num、i、j均存储于内存中
function add(uint num) view returns(uint){
num = num+1;
return num;
}
function test() view returns(uint,uint){
uint i = 2 ;
uint j = add(i);
return (i,j);
}
// 修改区块链上的值
function changeIt(){
num1 = 1000;
}
?2.结构体storage转storage
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal 2.storage可以接受storage的值,并且storage的改动影响其它storage ?
contract STS{ //此例temp,student1均为storage
struct stu{
uint id;
string name;
}
stu student1;
function structtest(stu storage temp) internal{ //传入storage结构体
student1=temp; //赋值
temp.id=2; //即使只是修改并未再次赋值,student1的id也会改变
}
function tets() public view returns(uint){
structtest(student1);
return (student1.id);
}
}
?3.结构体中的mapping特性
pragma solidity ^0.4.0;
contract structTest{
struct student{
uint grade;
string name;
mapping(uint=>string) map;
}
student meimei; // 默认为storage类型,只能够用storage类型来操作结构体中的mapping类型
function init() view returns(uint,string,string){
// 1.初始化时忽略mapping类型
student memory s = student(100,"BuLiangShuai");
// s.map[0] = "HelloWorld"; 2.不能直接用memory类型的对象直接操作struct中的mapping类型
meimei = s; // 将内存中的s对象赋值给像meimei这种区块链网络上的storage
meimei.map[0] = "HelloWorld"; // 我们只能通过storage对象来操作结构体中的mapping属性
return (s.grade,s.name,meimei.map[0]);
}
}
?
4.结构体memory转storage
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal 2.storage可以接受memory的值 3.memory的改动不影响storage 4.storage的改动不影响memory
pragma solidity ^0.4.0;
contract structTest{
struct student{
uint grade;
string name;
}
student stu;
// 函数的形参传递了指针
function test(student memory s) internal{
// 把s的值赋值给了区块链上的stu
stu = s;
// 修改函数形参的s,只是修改了其内存中的空间,没有修改掉区块链上的空间,因为两个空间完全独立
s.name = "BuLiangShuai";
}
function call() returns(string){
// 内存中开辟空间
student memory tmp = student(100,"tmp");
test(tmp);
return stu.name;
}
}
5.结构体storage转memory
1.要是函数以结构体作为参数,那么函数修饰符必须有private/internal 2.storage可以接受memory的值 3.memory的改动不影响storage 4.storage的改动不影响memory
pragma solidity ^0.4.0;
contract structTest{
struct student{
uint grade;
string name;
}
student stu = student(100,"stu");
// s形参是引用
function test(student storage s) internal{
// meimei是内存中的一个副本,把s引用的stu的内容拷贝给了meimei这个内存对象
student memory meimei = s;
// 修改meimei的值不会修改stu的值,因为两者的空间完全不同
meimei.name = "BuLiangShuai";
}
function call() returns(string){
test(stu);
return stu.name;
}
}
6.枚举
1.enum必须要有成员对象 ?2.enum中不能有汉字 ?3.enum后不能加分号(;) 4.enum的返回值(存储)是uint类型,且满足最小匹配原则返回
pragma solidity ^0.4.0;
contract enumTest{
uint fengjie = 0;
// 1.enum必须要有成员对象
// 2.enum中不能有汉字
// 3.enum后不能加分号(;)
// 4.enum的返回值(存储)是uint类型,且满足最小匹配原则返回
enum girl{fengjie,binbin,yuanyuan} // 0,1,2
girl dataGirl = girl.fengjie;
function getEnum() view returns(girl){
return girl.yuanyuan;
}
function oneNightDate() returns(string){
require(dataGirl==girl.fengjie);
dataGirl = girl.binbin;
return 'data with fengjie';
}
function secondNightDate() returns(string){
require(dataGirl==girl.binbin);
return 'data with binbin';
}
}
|