solidity函数部分
pragma solidity ^0.4.16;
//这部分要理解清楚 memory 和 storage 的不同
/* storage 函数外部的变量默认存储在storage
memory 函数内部的变量默认存储为memory中
详情见如下表中
storage memory
存储的变量 函数外部声明的变量,全局变量 函数内部声明的变量
存储的位置 区块链上,永久存储 内存中,运行完销毁
运行的位置 区块链网络 单个节点
传递属性 指针传递 值传递
参考资料:https://me.tryblockchain.org/solidity-data-location.html#fn1
https://blog.csdn.net/liyuechun520/article/details/78408588?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.nonecase
*/
//结构体部分
contract structTest{
struct stu{
uint id;
string name;
mapping(uint => string) mapTest;
}
function init() public view returns(uint,string){
//默认初始化顺序为结构体中变量的声明顺序
stu memory student1 = stu(1234,"xujialu");
return(student1.id,student1.name);
}
function init2() public view returns(uint,string){
//也可以指定变量进行初始化
stu memory student2 = stu({name:"kaikai",id:22});
return(student2.id,student2.name);
}
stu studentTest; //默认storage存储
function mappingTest() public view returns(uint,uint,string,string){
//这里默认新建的结构体是storage类型的指针,需要用关键字memory来声明
stu memory student3 = stu({name:"houzi",id:20});
//尝试操作stu的mapping
//student3.mapping[0] = "flag";
//student3是memory类型的指针相当于
//这里只有memory类型赋值给storage,后续不相关
studentTest = student3;
studentTest.id = 30;
studentTest.mapTest[0] = "xujialu";
return(studentTest.id,student3.id,studentTest.mapTest[0],student3.name);
}
//默认的函数参数,返回值,都是memory类型
function assign(stu s) internal {
// stu tem = s; 错误,不能这样写
}
//storage 转 storage
stu s;
function assigntwo(stu storage stemp) internal{
stu temp = stemp;
temp.id = 999;
}
function calltwo() returns(uint){
assigntwo(s);
return s.id; // 变味了999;
}
//
}
//memory赋值给局部变量 由于在区块链中,storage必须是静态分配存储空间。
//局部变量虽然是一个storage的,但它仅仅是一个storage类型的指针。如果进行这样的赋值,实际会产生一个错误。
contract MemoryToLocalVar{
struct S{string a;uint b;}
//默认参数是memory
function memoryToLocal(S s) internal{
//默认的变量是storage的指针
//Type struct MemoryToLocalVar.S memory is not implicitly convertible to expected type struct MemoryToLocalVar.S storage pointer.
//S tmp = s;
//修改变量为memory类型
S memory tmp = s;
}
}
//storage转为memory 将storage转为memory,实际是将数据从storage拷贝到memory
contract StorageToMemory{
struct S{string a;uint b;}
S s = S("storage", 1);
function storageToMemory(S storage x) internal{
S memory tmp = x;//由Storage拷贝到memory中
//memory的修改不影响storage
tmp.a = "Test";
}
function call() returns (string){
storageToMemory(s);
return s.a;
}
}
//在上面的例子中,我们看到,拷贝后对tmp变量的修改,完全不会影响到原来的storage变量。
//memory转为memory memory之间是引用传递,并不会拷贝数据。
contract MemoryToMemory{
struct S{string a;uint b;}
//默认参数是memory
function memoryToMemory(S s) internal{
S memory tmp = s;
//引用传递
tmp.a = "other memory";
}
function call() returns (string){
S memory mem = S("memory", 1);
memoryToMemory(mem);
return mem.a;//other memory
}
}
//在上面的代码中,memoryToMemory()传递进来了一个memory类型的变量,在函数内将之赋值给tmp,修改tmp的值,发现外部的memory也被改为了other memory