Solidity 数据存储

本文详细解释了Solidity中的三种数据存储方式——storage、memory和calldata的差异。storage数据在函数结束后保留且可修改,memory数据在函数执行完毕后删除但可修改,而calldata数据不可修改且仅用于读取。通过示例合约,展示了如何在不同场景下使用这些类型,并说明了为何memory类型能被返回而calldata不能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:本文介绍了 Soldiity 存储类型的区别。

Solidity 的数据有三种存储形式:storage, memory, calldata.

它们的区别如下:

数据存储形式生命周期可修改性
storage永久可修改数值
memory函数结束可修改数值
calldata函数结束不可修改数值

也就是说:

  1. 当函数运行结束后,storage 类型的数据会被保留,而 memorycalldata 类型的数据会被删除。
  2. storagememory 类型的数据可以被修改,而 calldata 类型的数据只可读不可写。

我们可以通过一个例子来理解区别:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract SimpleContract {
	string public data;

	// calldata 使用示例
	function useData(string calldata _data) external {
		// 该函数通过复制操作,进行存储类型的转换
		// 从 calldata 类型的 _data 转换为了 storage 类型的 data
		data = _data;
	}

	// memory 使用示例
	function modifyData(string calldata _data) external pure returns (string memory) {
		// 第一步,声明 memory 类型的变量 newData
		// 再通过复制操作将 _data 的值存入到 newData 当中
		string memory newData = _data;
		
		// 第二步,在 newData 后添加 " modified" 字符串
		// 要点1:abi.encodePacked(...) 是 Solidity 内置函数
		// 它可以将字符串连接在一起,并以字节数组的形式返回
		// 要点2:string(...) 用来将返回的字节数组转化为字符串形式
		newData = string(abi.encodePacked(newData, " modified"));
		
		// 第三步,返回修改过的 newData 数值
		// 要点1:合约函数本身没有返回数值的能力
		// EVM 会将 memory 类型的 newData 拷贝到返回数据缓存区中
		// 然后在函数周期结束后删除 newData 的数据
		// 要点2:calldata 无法被 EVM 放入返回数据缓存区中
		// 这就是为什么 calldata 无法返回而 memory 可以返回
		return newData;
	}
}

通过以上例子我们可以看到:

  1. calldata 类型的数据可以进行复制操作,可以将它的值复制到 storagememory 类型的变量中。
  2. memory 类型的数据不仅可以进行复制操作,还可以被函数修改和返回。
  3. storage 类型的数据不仅可以进行以上操作,还可以函数运行结束后被调用。

在 Remix 中运行效果如下:
代码效果演示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值