在以太坊Solidity,"记忆"的目的是什么?关键词?

时间:2015-11-21 02:48:21

标签: ethereum

在查看样本合同时,有时会在方法中使用" memory"有时它们不是。有什么区别?

2 个答案:

答案 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