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

10

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

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

我的代码:

pragma solidity ^0.8.5;

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

  function getHelloMessage() public view returns (string){
    return helloMessage;
  }
}
3个回答

8

您需要返回 string memory 而不是 string

示例:

function getHelloMessage() public view returns (string memory) {
    return helloMessage;
}
memory关键字是变量数据位置

5

对于那些阅读本文且拥有类似代码的人,"memory" 可能并不是你需要使用的正确术语。你可能需要使用 "calldata" 或者 "storage" 这些词来代替。以下是解释:

Memory, calldata(和 storage) 是 Solidity 变量存储值的方式。

例如:

1. Memory:以下是使用 "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)
    }
}

注意在私有函数中,'arrayToModify' 是数组的一个拷贝,并没有引用(或指向)传递给私有函数的数组,因此 'values' 数组并未被更改。

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

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变量引用了传入的数组并对其进行修改


3
问题是关于函数返回值中的内存类型,而不是参数。 - Rajan Lagah

3

使用string memory代替string

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

示例代码:数据位置


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接