Solidity值传递
pragma solidity ^0.4.4;
contract Person{
uint _age;
function Person(uint age) {
_age = age;
}
function f(){
modify(_age);
}
function modify(uint age){
age = 100;
}
function age() constant returns (uint){
return _age;
}
}

Solidity引用类型(storage/memory)
pragma solidity ^0.4.4;
contract Person{
string _name;
function Person(string name) {
_name = name;
}
function f(){
modify(_name);
}
//memory storage
function modify(string storage name) internal{
bytes(name)[0] = "S";
}
function name() constant returns (string){
return _name;
}
}

Solidity值类型与引用类型
也许对于很多有开发经验的童鞋来说,大家会以为Solidity语法非常简单,其实不然,Solidity还是存在很多和其他语言不一样的坑,下面是Solidity的相关语法细节以及注意事项。
先来看看有哪些类型属于值类型,哪些属于引用类型。
值类型(Value Type)
值类型包含:
布尔(Booleans)整型(Integer)地址(Address)定长字节数组(fixed byte arrays)有理数和整型(Rational and Integer Literals,String literals)枚举类型(Enums)函数(Function Types)
有其他语言开发经验的童鞋都知道,值类型传值时,会临时拷贝一份内容出来,而不是拷贝指针,当你修改新的变量时,不会影响原来的变量的值。
例如:
int a = 100; // a == 100
int b = a; // b == 100,a == 100
b = 300; // b == 300,a == 100
由上面的数据看,执行 b = a时,会将a的值临时拷贝一份传给b,所以当你修改b时,其实与a没任何关系。
引用类型(Reference Types)
引用类型包含:
不定长字节数组(bytes)字符串(string)数组(Array)结构体(Struts)
引用类型,赋值时,我们可以值传递,也可以引用即地址传递,如果是值传递,和上面的案例一样,修改新变量时,不会影响原来的变量值,如果是引用传递,那么当你修改新变量时,原来变量的值会跟着变化,这是因为新就变量同时指向同一个地址的原因。
引用类型中如何类比值传递?
值传递伪代码(以iOS中可变字符串NSMutableString为例子):
//创建一个可变的字符串name
NSMutableString *name = [@"wt" mutableCopy]; // name == "wt"
NSMutableString *name1 = [name copy]; //name1 == "wt", name == "wt"
name1 = "十二指环"; //name1 == "十二指环",name == "wt"
引用类型中如何类比引用传递?
//创建一个可变的字符串name
NSMutableString *name = [@"wt" mutableCopy]; // name == "wt"
NSMutableString *name1 = name; //name1 == "wt", name == "wt"
name1 = "十二指环"; //name1 == "十二指环",name == "十二指环"
引用类型memory/storage
引用类型的变量有两种类型,分别是memory和storage。
memory(值传递)默认
当引用类型作为函数参数时,它的类型默认为memory,函数参数为memory类型的变量给一个变量赋值时,这个变量的类型必须和函数参数类型一致,所以我们可以写成string memory name1 = name;,或者var name1 = name;,var声明一个变量时,这个变量的类型最终由赋给它值的类型决定。
任何函数参数当它的类型为引用类型时,这个函数参数都默认为memory类型,memory类型的变量会临时拷贝一份值存储到内存中,当我们将这个参数值赋给一个新的变量,并尝试去修改这个新的变量的值时,最原始的变量的值并不会发生变化。
storage(指针传递)
pragma solidity ^0.4.4;
contract Person {
string public _name;
function Person() {
_name = "wt";
}
function f() {
modifyName(_name);
}
function modifyName(string name) {
var name1 = name;
bytes(name1)[0] = 'W';
}
}
当函数参数为memory类型时,相当于值传递,而storage类型的函数参数将是指针传递。
如果想要在modifyName函数中通过传递过来的指针修改_name的值,那么必须将函数参数的类型显示设置为storage类型,storage类型拷贝的不是值,而是_name指针,当调用modifyName(_name)函数时,相当于同时有_name,name,name1三个指针同时指向同一个对象,我们可以通过三个指针中的任何一个指针修改他们共同指向的内容的值。
备注:
function modifyName(string storage name) {
var name1 = name;
bytes(name1)[0] = 'L';
}
等价于:
function modifyName(string storage name) {
string storage name1 = name;
bytes(name1)[0] = 'L';
}
上面的代码会在Remix中编译报错,原因是函数默认为public类型,但是当我们的函数参数如果为storage类型时,函数的类型必须为internal或者private
正确代码
pragma solidity ^0.4.4;
contract Person {
string public _name;
function Person() {
_name = "liyuechun";
}
function f() {
modifyName(_name);
}
function modifyName(string storage name) internal {
var name1 = name;
bytes(name1)[0] = 'L';
}
}
小结
Solidity编程语言中有哪些是值类型,哪些是引用类型,以及值类型和引用类型的区别我们进行简单的区分。【PS:Solidity值类型中,赋值时我们始终记住传的是值,改变新变量,不会影响原值,而引用类型就有两种可能】
在引用类型中的memory和storage的正确使用,才能不影响值的变化。
Solidity值与引用类型详解
本文深入解析Solidity中的值类型与引用类型,包括它们的定义、特性及使用场景,如布尔、整型、地址等值类型和字符串、数组等引用类型。详细对比了值传递与引用传递的区别,以及在智能合约编程中如何正确使用memory和storage。
554

被折叠的 条评论
为什么被折叠?



