news 2026/9/15 11:19:07

WTF-Solidity 入门第八讲:Solidity 变量初始值全解析 —— 默认值与 `delete` 操作符实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WTF-Solidity 入门第八讲:Solidity 变量初始值全解析 —— 默认值与 `delete` 操作符实战指南

WTF-Solidity 入门第八讲:Solidity 变量初始值全解析 —— 默认值与delete操作符实战指南

【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程,供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity

本讲内容基于 WTF-Solidity 极简入门教程第 8 讲(中文原版 08_InitialValue/readme.md 及西班牙语版 Languages/es/08_ValorInicial_es/readme.md)编写。在 Solidity 中,声明但未赋值的变量会自动获得其类型的"初始值"(默认值),理解这一机制是写出安全、可预期合约的基础。读完本讲,你将完整掌握值类型、引用类型变量的默认初始值规则,并能熟练使用delete操作符将任意变量一键恢复为初始状态,同时学会在 Remix 中通过public变量的getter函数逐项验证这些行为。

一、什么是变量初始值

在 Solidity 中,当你声明一个变量却没有给它赋值时,编译器并不会让它处于"未定义"状态,而是会为它赋予一个与该类型对应的默认初始值。这一点与许多高级语言(如 JavaScript 中未初始化变量为undefined)不同:Solidity 中的变量永远有确定的值。

从 EVM 的底层视角看,合约的存储(storage)槽位默认是清零的,因此凡是被声明而未显式赋值的状态变量,最终都会收敛到"该类型所表示的 0"——布尔值就是false、数值就是0、地址就是零地址address(0)。本讲后续介绍的所有初始值,本质上都是"0 在该类型中的表现形式"。

二、值类型变量的初始值

Solidity 中各类值类型变量的默认初始值如下表所示:

类型默认初始值说明
booleanfalse布尔假
string""空字符串
int0有符号整数 0
uint0无符号整数 0
enum枚举中的第一个元素即索引0对应的枚举项
address0x0000000000000000000000000000000000000000address(0),零地址
functioninternal空白函数不执行任何逻辑的函数
functionexternal空白函数不执行任何逻辑的函数

对应的合约代码(摘自 08_InitialValue/InitialValue.sol)如下:

// SPDX-License-Identifier: MIT pragma solidity ^0.8.34; contract InitialValue { // 值类型 bool public _bool; // false string public _string; // "" int public _int; // 0 uint public _uint; // 0 address public _address; // 0x0000000000000000000000000000000000000000 enum ActionSet { Buy, Hold, Sell} ActionSet public _enum; // 第一个元素,即索引 0 的 Buy function fi() internal{} // internal 空白函数 function fe() external{} // external 空白函数 }

几个值得注意的细节:

  • 枚举的初始值:枚举类型ActionSet { Buy, Hold, Sell }声明后未赋值时,其默认值是第一个元素Buy,底层对应索引0。也就是说,枚举的初始值不是"随机一个成员",而是始终收敛到0号成员。
  • 函数的初始值:无论是internal还是external的函数类型变量,初始值都是一个空白函数(empty function),调用它不会有任何实际行为。这也是"0 值"在函数类型上的体现。
  • 验证方式:由于上述变量都被声明为public,Solidity 会自动为它们生成getter函数,你可以直接在 Remix 的部署面板中点击对应按钮,读取并确认每个变量的初始值。

三、引用类型变量的初始值

引用类型mappingstructarray)的初始值规则可以归纳为一句话:其内部所有成员/元素都被设置为各自类型的默认值。具体表现如下:

类型默认初始值说明
mapping所有元素均为其键/值类型的默认值例如mapping(uint => address)的每个槽位值都是address(0)
struct所有成员均设为其类型的默认值例如含两个uint256成员的 struct,初始为(0, 0)
动态数组uint[][]空数组,长度为 0
静态数组uint[8][0, 0, 0, 0, 0, 0, 0, 0]所有元素均为元素类型的默认值

对应的合约代码(继续阅读 08_InitialValue/InitialValue.sol):

// 引用类型 uint[8] public _staticArray; // 所有成员设为其默认值的静态数组 [0,0,0,0,0,0,0,0] uint[] public _dynamicArray; // `[]` mapping(uint => address) public _mapping; // 所有元素都为其默认值的 mapping // 所有成员设为其默认值的结构体 0, 0 struct Student{ uint256 id; uint256 score; } Student public student;

要点说明:

  • mapping无法遍历且不可见"全部元素",它的初始值体现在"任何键查询到的值都是该值类型的默认值"——例如上例中_mapping(0)_mapping(1)查询结果均为0x0000...0000
  • 静态数组与动态数组的初始值不同:动态数组初始长度为0(空数组[]),而静态数组的长度在声明时已固定(如uint[8]固定为 8 个元素),其初始值为 8 个0
  • struct的初始值逐成员递归Studentidscore两个uint256成员初始都是0,即(0, 0)

四、delete操作符:一键恢复初始值

delete是 Solidity 提供的一个特殊操作符,语法为delete a,其作用是把变量a的当前值替换为其类型的初始值。可以把它理解为"重置变量"。

合约示例(摘自 08_InitialValue/InitialValue.sol):

// delete 操作符 bool public _bool2 = true; function d() external { delete _bool2; // delete 会让 _bool2 变为默认值,即 false }

上例中,_bool2在声明时被显式赋值为true,而一旦调用d()执行delete _bool2,它的值就会被重置为false

delete对不同类型的重置效果归纳如下:

操作效果
delete布尔/数值/地址重置为false/0/address(0)
delete动态数组长度变为0,成为空数组[]
delete静态数组所有元素恢复为元素类型的默认值
delete结构体所有成员恢复为各自类型的默认值
delete枚举重置为第一个枚举元素(索引 0)
delete映射映射中已存在的键值对被移除(恢复到未写入的默认状态)

安全提示delete是一个会真实改变链上状态的写操作,调用时需考虑 gas 成本(尤其是对大数据量结构体或数组执行delete时,需要为逐槽位清零支付存储 gas);同时应结合本仓库安全专题(如 S01_ReentrancyAttack)的教训,在涉及状态重置的业务逻辑中做好访问控制与重入防护。

五、在 Remix 上验证:实战步骤

下面在 Remix IDE 中部署合约,逐步验证上述初始值与delete行为。完整的可运行源码见 08_InitialValue/InitialValue.sol(西班牙语注释版见 Languages/es/08_ValorInicial_es/InitialValue.sol)。

步骤 1:编译并部署合约打开 Remix,新建文件InitialValue.sol并粘贴上述完整合约代码,选择^0.8.34及以上版本的编译器完成编译,然后在"部署与运行"面板中部署InitialValue合约。

步骤 2:查看各变量的初始值部署完成后,面板会为每个public变量自动生成对应的getter按钮。逐个点击即可读取到声明但未赋值变量的初始值——值类型(_bool_string_int_uint_address_enum)与引用类型(_staticArray_dynamicArray_mappingstudent)均显示为上文表格中的默认值:

步骤 3:调用delete并验证重置效果点击d函数按钮(或按上图中各delete对应函数)执行delete _bool2,随后再次读取_bool2,可以看到它从true被重置为false;若预先对_staticArraystudent等写入数据,执行delete后它们同样会恢复到各自的默认初始值:

通过以上三个步骤,你可以直观地确认:"声明未赋值 → 默认初始值"与"delete → 恢复初始值"这两条规则对值类型和引用类型都成立

六、仓库源码与多语言对照

本讲内容在仓库中有完整的中、英、西等多语言实现,便于对照学习:

  • 中文版:源码 08_InitialValue/InitialValue.sol、教程 08_InitialValue/readme.md;另在 src/08_InitialValue 目录下也保留了该讲的镜像副本。
  • 西班牙语版:源码 Languages/es/08_ValorInicial_es/InitialValue.sol、教程 Languages/es/08_ValorInicial_es/readme.md。
  • 英语版:见 Languages/en/08_InitialValue_en。

三份源码在合约逻辑上完全一致,仅在注释语言上有所不同,读者可以对照阅读,同时巩固 Solidity 术语的双语表达。教程体系方面,本讲属于 WTF-Solidity 基础部分,建议结合前序的 07_Mapping(映射)与 06_ArrayAndStruct(数组与结构体)一起学习,以理解引用类型的存储行为。

七、小结

本讲围绕"变量初始值"这一 Solidity 基础但关键的概念,梳理了完整规则:

  1. 值类型boolfalsestring""int/uint0enum→ 第一个元素(索引 0),addressaddress(0),函数类型 → 空白函数。
  2. 引用类型mapping→ 所有元素均为默认值,struct→ 所有成员均为默认值,动态数组 →[],静态数组 → 所有元素均为默认值。
  3. 核心结论:变量被声明但没有赋值时,其值默认为该类型的初始值,本质上是"0 在对应类型中的表现形式"。
  4. delete操作符delete a可以把变量a的值删除并恢复为初始值,是合约中常用的状态重置手段。

掌握这些默认值规则,能帮助你在阅读他人合约、编写初始化逻辑以及排查"变量为什么是这个值"的问题时更加得心应手,也是后续学习存储布局、代理合约升级等高级主题的必备基础。

【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程,供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 11:18:49

Python Sass 样式预处理 实战:安装、配置与生产部署验收

Python Sass 样式预处理 实战:安装、配置与生产部署验收工具地址:https://www.speedce.com 社区论坛:https://bbs.speedce.com 联系:speedceadsgmail.com写在前面 围绕「Sass 样式预处理」,本文提供可落地的技术指南&a…

作者头像 李华