在查看样本合同时,有时会在方法中使用" memory"有时它们不是。有什么区别?
答案 0 :(得分:41)
如果没有 memory 关键字,Solidity会尝试在 storage 中声明变量。
Lead Solidity dev chriseth:“您可以将存储视为具有虚拟结构的大型数组......在运行时无法更改的结构 - 它由合同中的状态变量决定”。
也就是说,根据您的合同级变量声明,存储结构在合同创建时一成不变,并且未来的方法调用无法更改。但是 - 可以使用sendTransaction调用更改该存储的内容。这种调用改变了“状态”,这就是合同级变量被称为“状态变量”的原因。所以变量uint8 storagevar;在合同级别声明的值可以更改为uint8(0-255)的任何有效值,但类型为uint8的值的“slot”将始终存在。
如果在没有 memory 关键字的函数中声明变量,那么solidity将尝试使用当前编译的存储结构,但会产生意外结果。 memory 告诉solidity在方法运行时为变量创建一块空间,保证其大小和结构以供将来在该方法中使用。
内存不能在合同级别使用。只在方法中。
请参阅常见问题解答中的the entry "What is the memory keyword? What does it do?"。我在这里引用它:
以太坊虚拟机有三个可以存储项目的区域。
第一个是“存储”,其中包含所有合同状态变量。每个合同都有自己的存储空间,它在函数调用之间是持久的,使用起来非常昂贵。
第二个是“记忆”,这用于保存临时值。它在(外部)函数调用之间被擦除,并且使用起来更便宜。
第三个是堆栈,用于保存小的局部变量。它几乎可以免费使用,但只能保留有限数量的值。
对于几乎所有类型,您都无法指定它们应存储在何处,因为它们在每次使用时都会被复制。
所谓的存储位置很重要的类型是结构和数组。如果你是在函数调用中传递这些变量,如果数据可以保留在内存中或保留在存储中,则不会复制它们的数据。这意味着您可以在被调用函数中修改其内容,并且这些修改仍将在调用者中可见。
存储位置有默认值,具体取决于它所涉及的变量类型:
- 状态变量始终存储
- 函数参数始终在内存中
- 默认情况下结构,数组或映射类型引用存储的局部变量
- 值类型的局部变量(即,数组,结构和映射都不存储)存储在堆栈中
答案 1 :(得分:0)
memory
定义了 Solidity 中的一个数据位置,它只能在运行时临时保存值。
Solidity 中的 memory
变量只能在方法中声明并且通常使用在方法参数中。一个不能保存在区块链中的短期变量......它只在函数执行期间保存值,执行后其值销毁。
看一下示例函数 f()
,其中我使用 memory
关键字声明了一个指针。它不会改变变量 User
的值,而如果它是使用 { 声明的{1}} 会改变存储在区块链中的变量 storage
的值,并且值不会被销毁...
User