:Solidity 函数输出 return / returns 与解构式赋值全解析)
WTF-Solidity 极简入门第 4 讲Solidity 函数输出 return / returns 与解构式赋值全解析【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-SoliditySolidity 函数不仅可以通过return输出单一结果还天然支持一次返回多个变量、命名式返回以及用解构式赋值灵活读取全部或部分返回值。本文以 WTF-Solidity 仓库第 4 讲 Return.sol 为源码骨架逐段讲解return与returns的职责分工、命名式返回的自动初始化机制、数组返回值的内存定位约束并结合 Remix 部署截图给出可直接复现的验证流程。读完本文你将掌握多返回值函数的声明与调用、命名式返回的两种写法以及在合约内部安全读取返回值的方法。本讲是 WTF-Solidity 极简入门系列的第 4 讲前置基础是第 3 讲Solidity 函数其中涉及的数据位置storage/memory/calldata将在第 5 讲数据存储与作用域中系统展开。本讲配套源码同时提供英文版 Languages/en/04_Return_en/Return.sol 与中文版 04_Return/Return.sol两者代码逻辑完全一致均可直接编译部署。一、函数输出的两个关键字return 与 returnsSolidity 中与函数输出相关的关键字有两个return和returns它们虽然拼写相近但职责完全不同很容易混淆returns跟在函数名之后用于声明函数返回值的类型可选地声明变量名相当于输出接口的签名声明return用在函数主体内部用于返回指定的变量或值相当于把数据实际交出去的动作。从仓库源码 Return.sol 可以看到二者的组合用法// SPDX-License-Identifier: MIT pragma solidity ^0.8.34; contract Return { // 返回多个变量 function returnMultiple() public pure returns(uint256, bool, uint256[3] memory){ return(1, true, [uint256(1),2,5]); } }这段代码声明了一个returnMultiple()函数returns(uint256, bool, uint256[3] memory)声明了三个返回值一个uint256数值、一个bool布尔值、一个长度为 3 的uint256数组函数主体通过return(1, true, [uint256(1),2,5])按顺序返回三个值返回值必须与returns声明的类型、数量、顺序一一对应。数组字面量的类型陷阱returnMultiple()里有一个非常容易踩的坑[1, 2, 3]这样的数组字面量在 Solidity 中默认会被推断为uint8[3]所有字面量都能装进uint8。如果直接写return(1, true, [1,2,5])编译器会因类型不匹配uint8[3]无法隐式转换为声明的uint256[3]而报错。因此源码中刻意将首个元素强转为uint256[uint256(1),2,5]强转后整个数组字面量的类型即被确定为uint256[3]其余元素2、5随之被纳入该类型。这是多返回值数组场景下最典型的编译错误来源务必牢记。数组返回值必须用 memory 修饰注意returns(uint256, bool, uint256[3] memory)中的memory关键字——引用类型数组、结构体、映射作为返回值时必须显式声明数据位置。这里memory表示返回值临时存放在内存中不会写链gas 开销远低于storage。关于storage/memory/calldata三种数据位置的详细对比与赋值行为可参考仓库中第 5 讲数据存储与作用域。二、命名式返回让 Solidity 自动返回在returns中除了声明类型还可以声明返回变量的名称。一旦为返回值命名Solidity 会自动在函数入口处将这些变量初始化为默认值uint256为0、bool为false、数组为空并在函数执行完毕时自动返回它们的值——无需再写return语句。仓库源码 Return.sol 中的returnNamed()就是标准写法// 命名式返回 function returnNamed() public pure returns(uint256 _number, bool _bool, uint256[3] memory _array){ _number 2; _bool false; _array [uint256(3),2,1]; }returns(uint256 _number, bool _bool, uint256[3] memory _array)同时声明了返回值的类型和名称函数体内只需要对命名变量_number、_bool、_array赋值函数结束时 Solidity 会自动把这些变量的当前值作为返回值返回由于没有使用return语句整体代码更简洁可读性更好。命名式返回 return两种方式可以共存命名式返回并不意味着禁用return。仓库源码 Return.sol 中的returnNamed2()演示了二者的组合// 命名式返回依然支持 return function returnNamed2() public pure returns(uint256 _number, bool _bool, uint256[3] memory _array){ return(1, true, [uint256(1),2,5]); }这里虽然已经命名了_number、_bool、_array但函数体仍用return(1, true, [uint256(1),2,5])显式返回。当同时使用时return语句的值优先于命名变量的当前值。因此returnNamed()返回(2, false, [3,2,1])returnNamed2()返回(1, true, [1,2,5])与returnMultiple()完全一致。这个对比清晰说明了两种机制各自生效的场景命名式返回适合在函数体内分步计算、最后统一输出的写法显式return适合结果已就绪、立即返回的写法。三、解构式赋值读取全部或部分返回值Solidity 内部支持元组tuple类型——即一组元素类型可以不同、但元素个数在编译期固定的对象列表。多返回值函数本质上返回的就是一个元组因此可以用解构式赋值destructuring assignment一次性把多个返回值取出来。读取全部返回值仓库源码 Return.sol 中的readReturn()演示了完整读取// 读取返回值解构式赋值 function readReturn() public pure{ // 读取全部返回值 uint256 _number; bool _bool; bool _bool2; uint256[3] memory _array; (_number, _bool, _array) returnNamed(); // 读取部分返回值解构式赋值 (, _bool2, ) returnNamed(); }要点先声明与返回值类型一一对应的目标变量赋值号左侧用括号包裹、变量之间以逗号分隔按返回顺序排列左侧变量个数与返回值个数必须匹配或者按下一节的方式用逗号占位留空。读取部分返回值逗号占位不想读取的返回值位置可以直接留空仅保留逗号占位符。上例第二段代码(, _bool2, ) returnNamed();只把第二个返回值bool类型赋给_bool2而第一个_number和第三个_array返回值被逗号占位、直接丢弃。这种写法在只需要函数众多返回结果中的某一项时非常实用避免了声明一堆用不到的变量。值得注意的是readReturn()本身声明为public pure且没有返回值它的价值在于演示解构赋值的合法语法与写法——你可以在任何合约函数内部用同样的方式承接其他函数的返回值并将其作为后续业务逻辑的输入。四、在 Remix 上验证三种返回方式本讲配套截图 Languages/en/04_Return_en/img/4-1.png 展示了在 Remix IDE 中部署Return合约并调用各函数的真实结果复现步骤如下打开 Remix IDE新建文件并把仓库中 Languages/en/04_Return_en/Return.sol 的完整代码粘贴进去也可以直接用04_Return/Return.sol内容等价在编译面板选择Return合约并完成编译本讲源码使用pragma solidity ^0.8.34请确保编译器版本兼容例如 0.8.18 及以上均可切换至Deploy Run Transactions面板Environment 选择 Remix VM点击Deploy部署合约在 Deployed Contracts 区域依次点击并查看函数输出。从截图中可以看到三个函数的真实返回结果函数返回值returnMultiple()0: uint256 1、1: bool true、2: uint256[3] [1,2,5]returnNamed()0: uint256 _number 2、1: bool _bool false、2: uint256[3] _array [3,2,1]returnNamed2()0: uint256 _number 1、1: bool _bool true、2: uint256[3] _array [1,2,5]注意 Remix 面板中的uint256[3]输出会直接展示为数组字面量形式如[1,2,5]便于直观核对。命名式返回的函数在面板上还会显示变量名_number、_bool、_array这也是 Remix 中区分是否命名返回的视觉特征。五、回到源码本讲实现与仓库结构本讲的核心实现非常精简全部逻辑浓缩在 Languages/en/04_Return_en/Return.sol英文版与 04_Return/Return.sol中文版两个文件中合约包含 4 个函数returnMultiple()无命名返回演示多类型返回值returnNamed()命名式返回自动返回returnNamed2()命名式返回 显式returnreadReturn()演示解构式赋值读取全部与部分返回值。作为WTF-Solidity 极简入门教程体系中的一环本讲向上承接第 3 讲函数public/pure等函数可见性与修饰符向下引出第 5 讲数据存储与作用域本讲反复出现的memory关键字正是该讲的核心概念之一。如果你想进一步了解uint256[3]这类数组类型在storage、memory、calldata三种位置下的行为差异直接进入第 5 讲即可。六、总结本讲围绕 Solidity 函数输出梳理了四个核心知识点return与returns的分工returns在函数名后声明返回类型与变量名return在函数体内返回实际值返回多个变量returns可声明多个返回值返回的数组字面量需注意默认uint8类型推断问题且引用类型返回值必须用memory修饰命名式返回在returns中命名返回变量后Solidity 自动初始化并自动返回也可与显式return混用return优先解构式赋值通过括号逗号语法一次读取全部返回值或用空位占位只读取部分返回值。这些能力在真实合约开发中非常常见——例如合约的批量查询接口一次返回多组状态、内部函数将计算结果打包交给外部调用方等场景都依赖对多返回值与解构赋值的熟练运用。掌握本讲内容后你可以在自己的合约中更灵活、更安全地设计函数输出接口。【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考