当前位置:网站首页>第96篇 笔记-solidity中的重载(Override)
第96篇 笔记-solidity中的重载(Override)
2022-07-21 10:37:00 【wonderBlock】
目录
1. 函数重载
合约可以具有多个不同参数的同名函数,称为"重写"或"重载"(override ),这也适用于继承函数。
以下示例展示了合约 A
中的重载函数 f
:
//SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;
contract A {
function f(uint _in) public pure returns (uint out) {
out = _in;
}
function f(uint _in, bool _really) public pure returns (uint out) {
if (_really)
out = _in;
}
}
重载函数也存在于外部接口中。如果两个外部可见函数仅区别于 Solidity 内的类型而不是它们的外部类型则会导致错误。
//SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;
contract A {
function f(B _in) public pure returns (B out) {
out = _in;
}
function f(address _in) public pure returns (address out) { // 报错
out = _in;
}
}
contract B {}
该合约无法编译通过;报错信息:
TypeError: Function overload clash during conversion to external types for arguments.
因为:以上两个 f
函数重载都接受了 ABI 的地址类型,虽然它们在 Solidity 中被认为是不同的。
2. 重载解析和参数匹配
通过将当前范围内的函数声明与函数调用中提供的参数相匹配,可以选择重载函数。 如果所有参数都可以隐式地转换为预期类型,则选择函数作为重载候选项。如果一个候选都没有,解析失败。
注解:返回参数不作为重载解析的依据。
//SPDX-License-Identifier: MIT
pragma solidity >=0.4.16 <0.9.0;
contract A {
function f(uint8 _in) public pure returns (uint8 out) {
out = _in;
}
function f(uint256 _in) public pure returns (uint256 out) {
out = _in;
}
}
合约编译部署正常,但是:
- 调用
f(50)
会导致类型错误,因为50
既可以被隐式转换为uint8
也可以被隐式转换为uint256
。 - 另一方面,调用
f(256)
则会解析为f(uint256)
重载,因为256
不能隐式转换为uint8
。
3. 版本 0.6.x 之后的更新
在 solidity 的 0.6.0 版本之后:
- 重写函数或修饰符时,必须使用新关键字
override
。 - 接口会自动作为
virtual,
在接口外部没有实现的函数必须标记为virtual
。 - 仅当函数被标记为
virtual
或在接口中定义时,才可以重写。 private
的函数是不可以标记为virtual
的。- 对于单继承,请在每个重写函数中添加
override
。 - 对于多继承,添加
override(A, B, ..),
在括号中列出所有覆盖函数的合约。
一个简单多继承的例子:
//SPDX-License-Identifier: MIT
pragma solidity ^0.6.10;
contract A {
uint public x;
function setValue(uint _x) public virtual { //增加 virtual
x = _x;
}
}
contract B {
uint public y;
function setValue(uint _y) public virtual { //增加 virtual
y = _y;
}
}
contract C is A, B {
function setValue(uint _x) public override(A,B) { // 重写 setValue
A.setValue(_x);
}
}
本文在 0.8.0 版本实测,不需要关键字 virtual 和 override 也可以:
pragma solidity >=0.4.16 <0.9.0;
contract A {
function f(uint _in) public pure returns (uint out) {
out = _in;
}
function f(uint _in, bool _really) public pure returns (uint out) {
if (_really)
out = _in;
}
}
但是在 0.8.0 版本的 GitHub - OpenZeppelin/openzeppelin-contracts: OpenZeppelin Contracts is a library for secure smart contract development. 中,大量使用了 virtual 和 override。
4. 可变性与可见性
重写函数只能将覆盖函数的可见性从 external
更改为 public
。
可变性可以按照以下顺序更改为更严格的一种: nonpayable
可以被 view
和 pure
覆盖。 view
可以被 pure
覆盖。 payable
是一个例外,不能更改为任何其他可变性。
示例:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Base {
function foo() virtual external view {}
}
contract Middle is Base {}
contract Inherited is Middle {
function foo() override public pure {}
}
5. 常见问题
pragma solidity ^0.4.17;
contract Overload{
//error,重名方法
function fun1(){}
function fun1(){}
//error,返回值不能作为判断依据
function fun2() returns(string){}
function fun2() returns(uint){}
//编译通过,参数类型不同可以作为重载的依据,但是传参<256时会报错,无法匹配方法
function fun4(uint _num) {}
function fun4(uint8 _num) {}
//编译通过,但两者(address 与 uint160)实际存储方式一致,故无法匹配
function fun5(uint160 account) {}
function fun5(address account) {}
}
边栏推荐
- 决策树_ID3_C4.5_CART
- MySQL creates new users and authorizes them
- Brief analysis of Redux technology stack (2): understanding saga's buffer and Chanel
- Dynamically generate excel forms in word documents (explanation of Fund announcement Series)
- Base64 encryption and decryption
- Information entropy_ Joint entropy_ Conditional entropy_ information gain
- 百度地图、高德地图、腾讯地图三位一体地图定位开发
- [untitled]
- Go处理字符串到合法文件名
- How to make the demand unable to go online smoothly as scheduled (IV) integration test stage
猜你喜欢
学习基础-单词记忆
Unity surface shader foundation memo
Policy mode rewriting if else advanced use
Dynamically generate excel forms in word documents (explanation of Fund announcement Series)
RNN之LSTM和GRU_Attention机制
Harbor仓库搭建及简单使用
day 3
游戏中的数学之各种插值
Alibaba cloud technology expert Yang Zeqiang: building observable capabilities on elastic computing cloud
特征抽取工具-Transformer-bert
随机推荐
Recursion_ Calculate f (n) =f (n-1) +f (n-2)
Single example of game code specification
Harbor warehouse construction and simple use
Jenkins安装并配置加速器
Learning foundation - word memory
Go之数组/切片
Redis主从复制与哨兵模式
Unity surface shader foundation memo
String类常用方法
day 2
【JS 逆向百例】某公共资源交易网,公告 URL 参数逆向分析
Virbox 编译器,支持全平台全架构的源代码加密
Nacos配置中心之环境准备
Random forest thought
Recommended system common terms
Data too long for column ‘......‘ at row 2
Day 10 (继承、重写与super的使用)
游戏中的数学之3D基础
Threadpooltaskexecutor uses
layaAir 实践初探