memory - 在以太坊 Solidity 中, "memory"关键字的用途是什么?

标签 memory blockchain ethereum solidity smartcontracts

在查看示例合约时,有时会在带有“内存”的方法中声明数组,有时则不会。有什么区别?

最佳答案

如果没有内存关键字,Solidity会尝试在存储中声明变量。

首席 Solidity 开发者 chriseth:“您可以将存储视为具有虚拟结构的大型数组……该结构在运行时无法更改 - 它由合约中的状态变量决定”。

也就是说,存储结构是在创建合约时根据合约级变量声明确定的,并且不能通过将来的方法调用进行更改。但是——该存储的内容可以通过调用 sendTransaction 来更改。此类调用会改变“状态”,这就是合约级变量被称为“状态变量”的原因。因此,在合约级别声明的变量 uint8 storage var; 可以更改为任何有效的 uint8 值 (0-255),但 uint8 类型值的“槽”将始终存在。

如果您在函数中声明变量时没有使用 memory 关键字,那么 Solidity 将尝试使用当前可以编译的存储结构,但可能会产生意外的结果。 内存告诉solidity在方法运行时为变量创建一 block 空间,保证其大小和结构以供将来在该方法中使用。

内存不能在合约级别使用。仅在方法中。

请参阅the entry "What is the memory keyword? What does it do?"在常见问题解答中。我在这里引用一下:

The Ethereum Virtual Machine has three areas where it can store items.

The first is “storage”, where all the contract state variables reside. Every contract has its own storage and it is persistent between function calls and quite expensive to use.

The second is “memory”, this is used to hold temporary values. It is erased between (external) function calls and is cheaper to use.

The third one is the stack, which is used to hold small local variables. It is almost free to use, but can only hold a limited amount of values.

For almost all types, you cannot specify where they should be stored, because they are copied everytime they are used.

The types where the so-called storage location is important are structs and arrays. If you e.g. pass such variables in function calls, their data is not copied if it can stay in memory or stay in storage. This means that you can modify their content in the called function and these modifications will still be visible in the caller.

存储位置有默认值,具体取决于它涉及的变量类型:

  • 状态变量始终存储在存储中
  • 函数参数始终位于内存中
  • 默认结构体、数组或映射类型引用存储的局部变量
  • 值类型的局部变量(即既不是数组,也不是结构体,也不是映射)存储在堆栈中

关于memory - 在以太坊 Solidity 中, "memory"关键字的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33839154/

相关文章:

php - 内存耗尽cakephp数据库查询

memory - 为什么将内存区域标记为非缓存?

C - 如何找到结构的大小?

python 版本与 json.dumps 冲突

blockchain - 使用 interface 和 delegateCall 调用外部 Solidity 合约

typescript - 从 Uniswap V2 获取正确的执行价格

C:在 0x0FFB0BA0 处抛出异常(ucrtbased.dll)

docker - 如何使用用于REST通信的端口映射Hyperledger Fabric对等体(2nd,3rd,4th)

blockchain - 我应该什么时候构建 Substrate 运行时模块而不是 Substrate 智能合约?

interface - 使用 Solidity : interface vs library? 的可升级智能合约