坚固性:函数中返回参数的数据位置必须"memory"或"calldata"



我正在Solidity中学习以太坊开发,并试图运行一个简单的HelloWorld程序,但遇到了以下错误:

数据位置必须是";存储器";或";calldata";用于函数中的return参数,但未给出任何参数。

我的代码:

pragma solidity ^0.8.5;
contract HelloWorld {
string private helloMessage = "Hello world";
function getHelloMessage() public view returns (string){
return helloMessage;
}
}

您需要返回string memory而不是string

示例:

function getHelloMessage() public view returns (string memory) {
return helloMessage;
}

memory关键字是可变数据位置。

对于那些阅读本文并拥有类似代码的人来说,"内存"可能不一定是正确的单词。您可能需要使用单词"calldata"或"storage"。这里有一个解释:

内存、调用数据(和存储(指Solidity变量存储值的方式。

例如:

1.内存:这里有一个使用单词"内存"的例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import 'hardhat/console.sol'; // to use console.log
contract MemoryExample {
uint[] public values;
function doSomething() public
{
values.push(5);
values.push(10);
console.log(values[0]); // logged as: 5
modifyArray(values);
}
function modifyArray(uint[] memory arrayToModify) pure private {
arrayToModify[0] = 8888;
console.log(arrayToModify[0]) // logged as: 8888 
console.log(values[0]) // logged as: 5 (unchanged)
}
}

注意"values"数组在私有函数中没有更改,因为"arrayToModify"是数组的副本,并且不引用(或指向传递给私有函数的数组(。

2.调用数据不同,可用于以只读方式传递变量:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
contract CallDataExample {
uint[] public values;
function doSomething() public
{
values.push(5);
values.push(10);
modifyArray(values);
}
function modifyArray(uint[] calldata arrayToModify) pure private {
arrayToModify[0] = 8888; // you will get an error saying the array is read only
}
}

3.存储:这里的第三个选项是使用"存储"关键字:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import 'hardhat/console.sol'; // to use console.log
contract MemoryExample {
uint[] public values;
function doSomething() public
{
values.push(5);
values.push(10);
console.log(values[0]); // logged as: 5
modifyArray(values);
}
function modifyArray(uint[] storage arrayToModify) private {
arrayToModify[0] = 8888;
console.log(arrayToModify[0]) // logged as: 8888
console.log(values[0]) // logged as: 8888 (modifed)
}
}

注意arrayToModify变量是如何通过使用memory关键字来引用传入的数组并对其进行修改的。

使用string memory而不是string

  • 存储-变量是一个状态变量(存储在区块链上(内存-变量
  • 列表项-在内存中,并且在调用函数时存在
  • calldata-包含函数参数的特殊数据位置,仅可用于外部函数

示例代码:数据位置

最新更新