通学智能合约系列(十七)--函数与Getter

大家好,这里是通学技术,承接上节,我们一起继续来学习智能合约系列。

16、函数小结

前面我们花费了巨多的篇幅来介绍函数,可见函数是多么的重要。不过当然也是,在面向对象的思想里,属性和行为构成了对象,正是因为我们千姿百态的行为,才构建了我们丰富多彩的世界。

这里我们针对我们所学的函数做一个小结吧。

首先,还是先请出我们的函数通用写法。

function  functionName(<parameter  types>) {
    
    private|internal|external|public} [pure|constant|view|payable] [returns(<return types>)]
  1. 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();
        }
        
    }
    
  2. internal 可以在内部被调用,不能在外部被调用,可以被继承.

    在这里说明一下,为什么redmix 输出控制台上,父合约的函数没有出现,就是因为这是外部调用,而privateinternal都是不能在外部调用的,所以不可见

    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();
        }
        
    }
    
  3. 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();
                   ^--------------^
    
  4. public 权限最大,可以在外部调用,可以被继承。

  5. pure 不会读取全局变量,更不会修改全局变量,一个固定的输入就会有一个固定的输出,不消耗gas.

  6. constant 在函数中,和view相同,在全局变量中,值用于byte1-byte32uint,int,string,代表数据不能够被修改,在0.5版本上已经删除。

  7. view值读取全局变量的值,不修改它。不消耗gas。

  8. payable 转账时必须加的关键字。

  9. 命名参数 {value:2,name:tong}

  10. 函数可以有多个返回值。

关于函数的基本特性,我们就更新到这里,下节,我们将来看看函数的其他重要特性。

17、全局变量自动getter函数

接触过java的同学们,应该对settergetter方法都不陌生,在silidity的世界里,getter方法也很重要,关于它,我们看看一下的例子吧。

pragma solidity ^0.4.16;


contract GetterTest{
    
    
    
    uint public num = 100;
    
    uint  num1 = 100;
    
}

编译部署后,大家可以看到,只出现了一个num方法。这是因为当public修饰的缘故。关于getter方法有三个特性,我们来看看吧。

  1. public修饰符修饰的属性,默认会生成一个get方法,供我们外部调用.
  2. 我们重新用该属性定义一个函数,默认的get函数就会被覆盖。
  3. 默认生成的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已经为我们这个复杂类型做了处理,我们只需要输入合理的参数即可。

在这里插入图片描述
面向区块链编程,构建可信社会。我们下节再见。

猜你喜欢

转载自blog.csdn.net/aiwaston/article/details/117969442
今日推荐