Solidity:函数中返回参数的数据位置必须是“内存”或“calldata”

Yas*_*ain 10 ethereum solidity

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

函数中返回参数的数据位置必须是“内存”或“calldata”,但没有给出。

我的代码:

pragma solidity ^0.8.5;

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

  function getHelloMessage() public view returns (string){
    return helloMessage;
  }
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*jda 8

您需要返回string memory而不是string.

例子:

function getHelloMessage() public view returns (string memory) {
    return helloMessage;
}
Run Code Online (Sandbox Code Playgroud)

关键字memory是可变数据位置


小智 5

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

内存、calldata(和存储)指的是 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 问题是关于函数返回中的内存类型而不是参数中的内存类型 (3认同)