Solidity:对于函数中的 return 参数,数据位置必须是 "memory" 或 "calldata"

Solidity: Data location must be "memory" or "calldata" for return parameter in function

我正在认真学习以太坊开发并尝试 运行 一个简单的 HelloWorld 程序但是 运行 出现以下错误:

Data location must be "memory" or "calldata" for return parameter in function, but none was given.

这是我的代码:

pragma solidity ^0.8.5;

contract HelloWorld {
  string private helloMessage = "Hello world";

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

您需要 return string memory 而不是 string

示例:

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

memory关键字是变量data location.

使用 string memory 而不是 string

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

示例代码:Data Locations

对于阅读本文并拥有类似代码的人来说,'memory' 可能不一定是适合您的正确词。您可能需要改用词 'calldata' 或 'storage'。这里有一个解释:

内存、调用数据(和存储)指的是 Solidity 变量如何存储值。

例如:

1.内存: 这里是一个使用单词 'memory':

的例子
// 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。 Calldata 不同,可用于传递变量 read-only:

// 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。存储: 这里的第三个选项是使用 'storage' 关键字:

// 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)
    }
}

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