通学智能合约系列(十六)--函数与Getter
Posted 通学技术
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通学智能合约系列(十六)--函数与Getter相关的知识,希望对你有一定的参考价值。
大家好,这里是通学技术,承接上节,我们一起继续来学习智能合约系列。
16、函数小结
前面我们花费了巨多的篇幅来介绍函数,可见函数是多么的重要。不过当然也是,在面向对象的思想里,属性和行为构成了对象,正是因为我们千姿百态的行为,才构建了我们丰富多彩的世界。
这里我们针对我们所学的函数做一个小结吧。
首先,还是先请出我们的函数通用写法。
function functionName(<parameter types>) {private|internal|external|public} [pure|constant|view|payable] [returns(<return types>)]
-
private
不能够被继承、不能够在外部被调用、可以在内部被调用。contract Father{ function noSmoking() private pure returns(string){ return "I'm not somking"; } function testFather() private pure returns(string){ // 可以在内部调用 return noSmoking(); // 不可以在外部调用 // return this.noSmoking(); } }
-
internal
可以在内部被调用,不能在外部被调用,可以被继承.在这里说明一下,为什么redmix 输出控制台上,父合约的函数没有出现,就是因为这是外部调用,而
private
和internal
都是不能在外部调用的,所以不可见pragma solidity ^0.4.16; contract Father{ function noSmoking() internal pure returns(string){ return "I'm not somking"; } function testFather() internal pure returns(string){ return noSmoking(); } } contract Son is Father{ function test() public pure returns(string){ return noSmoking(); } }
-
external
不能够在内部被调用,只能够在外部被调用,可以继承。如果强行调用,通过地址.
。pragma solidity ^0.4.16; contract Father{ function noSmoking() external pure returns(string){ return "I'm not somking"; } function testFather() public{ this.noSmoking(); } } contract Son is Father{ function test() public{ this.noSmoking(); } }
这里按照老师的写法,会报错如下,如果大家知道怎么解决,可以告诉我。原因是动态类型不能自动转类型,但是继承的话,是不影响的。
browser/Math.sol:12:16: TypeError: Return argument type inaccessible dynamic type is not implicitly convertible to expected type (type of first return variable) string memory. return this.noSmoking(); ^--------------^
-
public
权限最大,可以在外部调用,可以被继承。 -
pure
不会读取全局变量,更不会修改全局变量,一个固定的输入就会有一个固定的输出,不消耗gas
. -
constant
在函数中,和view
相同,在全局变量中,值用于byte1-byte32
,uint
,int
,string
,代表数据不能够被修改,在0.5
版本上已经删除。 -
view
值读取全局变量的值,不修改它。不消耗gas。 -
payable
转账时必须加的关键字。 -
命名参数 {value:2,name:
tong
} -
函数可以有多个返回值。
关于函数的基本特性,我们就更新到这里,下节,我们将来看看函数的其他重要特性。
17、全局变量自动getter函数
接触过java的同学们,应该对setter
和getter
方法都不陌生,在silidity
的世界里,getter
方法也很重要,关于它,我们看看一下的例子吧。
pragma solidity ^0.4.16;
contract GetterTest{
uint public num = 100;
uint num1 = 100;
}
编译部署后,大家可以看到,只出现了一个num
方法。这是因为当public
修饰的缘故。关于getter
方法有三个特性,我们来看看吧。
- public修饰符修饰的属性,默认会生成一个get方法,供我们外部调用.
- 我们重新用该属性定义一个函数,默认的get函数就会被覆盖。
- 默认生成的get函数是
external
权限的,不能够在合约的内部调用。
关于上面的第一点,我们已经说明了,那第二点和第三点,我们也来看看吧。
pragma solidity ^0.4.16;
contract GetterTest{
uint public num = 100;
// function num() external returns(uint){
// num = 200;
// return num;
// }
function test(){
// num();
this.num();
}
}
编译执行上述代码后,我们可以发现,num()
函数只会有一个,结果是200.可以说明是我们自己写的num()
函数,他覆盖了默认生成的num函数
。此外,我们只能通过this.num()
来调用,否则编译报错。说明我们默认生成的getter函数
是被external
修饰的。仅供外部调用。
上面我们说了基本类型,那么如果对于mapping
类型的数据,他会是怎么样的呢?相信聪明的小伙伴已经有答案了。没错,既然是key-value
型数据结构,那么自然符合通用规则。
mapping(uint => string) public map;
上述代码,就等价于
function map(uint key) external returns(string){
}
我在验证这块,又是遇到了前面同样的问题,如下代码编译报错:
function test2(){
map[1] = "tong";
}
function test3(uint key) returns(string){
return this.map(key);
}
又是memory
类型搞的鬼,等后续彻底搞定这个问题,在来会看这段代码吧。这里先设置一个锚点。
18、超级复杂的getter函数
在这一小节,我们看一个套娃模式的mapping
类型,生成的默认的getter
函数是怎样的呢?
pragma solidity ^0.4.16;
contract GetterTest{
mapping(uint => mapping(uint => mapping(uint => string))) public map;
function test(){
map[0][0][0] = "tongxuejishu";
}
}
至于这个类型,也不复杂,我们可以将它想想成一个三维空间,三个参数就是对应着三维坐标系的(x,y,z)
。根据这个坐标,确定一个点。好的是,solidity
已经为我们这个复杂类型做了处理,我们只需要输入合理的参数即可。
面向区块链编程,构建可信社会。我们下节再见。
以上是关于通学智能合约系列(十六)--函数与Getter的主要内容,如果未能解决你的问题,请参考以下文章