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

Posted

技术标签:

【中文标题】函数中返回参数的数据位置必须是“内存”,但没有给出【英文标题】:Data location must be "memory" for return parameter in function, but none was given 【发布时间】:2020-02-04 02:45:29 【问题描述】:

我在 remix 中尝试了像上面那样的solidity示例,solidity version > 0.5.0 但我现在收到此错误。 有什么办法可以解决这个错误?

contract MyContract 
    string value;

    function get() public view returns (string) 
        return value;
    

    function set(string _value) public 
        value = _value;
    

    constructor() public 
        value = "myValue";
    

【问题讨论】:

【参考方案1】:

你应该为字符串参数添加内存关键字,这是在solidity版本0.5.0中引入的

根据文档:

结构、数组或映射类型的所有变量的显式数据位置现在是强制性的。这也适用于函数参数和返回变量。例如,将 uint[] x = m_x 更改为 uint[] storage x = m_x,将函数 f(uint[][] x) 更改为函数 f(uint[][] memory x) 其中 memory 是数据位置,可能相应地被 storage 或 calldata 替换。请注意,外部函数需要带有 calldata 数据位置的参数。

更正的代码

contract MyContract 
    string value;

    function get() public view returns (string memory) 
        return value;
    

    function set(string memory _value) public 
        value = _value;
    

    constructor() public 
        value = "myValue";
    

请参阅官方documentation 了解版本 0.5.0 中所做的重大更改

【讨论】:

【参考方案2】:

Solidity 每天都会更新,因此您应该注意所做的更改。为此,请继续参考更新的 Solidity 文档。

代码应该是这样的:

contract MyContract 
    string value;

    function get() public view returns (string memory) 
        return value;
    

    function set(string memory _value) public 
        value = _value;
    

    constructor() public 
        value = "myValue";
    

contract MyContract 
    string value;

    function get() public view returns (string calldata) 
        return value;
    

    function set(string calldata _value) public 
        value = _value;
    

    constructor() public 
        value = "myValue";
    

【讨论】:

【参考方案3】:

引用类型的值可以通过多种不同的方式修改 名字。将此与您获得独立的值类型进行对比 每当使用值类型的变量时复制。正因为如此, 引用类型必须比值类型更仔细地处理。 目前,引用类型包括结构、数组和映射。如果 你使用引用类型,你总是必须明确地提供 存储类型的数据区域:内存(其生命周期是有限的 到外部函数调用),存储(状态所在的位置 变量被存储,其中生命周期被限制为 合同)或调用数据(包含 函数参数)。

Warning

在 0.5.0 版之前,数据位置可以省略,并且会根据变量类型、函数类型等默认为不同的位置,但现在所有复杂类型都必须给出明确的数据位置。

https://docs.soliditylang.org/en/latest/types.html#reference-types

所以你必须在字符串后面加上memorycalldata ,如下所示:

contract MyContract 
    string value;

    function get() public view returns (string memory) 
        return value;
    

    function set(string memory _value) public 
        value = _value;
    

    constructor() 
        value = "myValue";
    

还有一点需要注意的是,您不必再将 public 放在构造函数中:

警告:在 0.7.0 版本之前,您必须指定 构造函数可以是内部的,也可以是公共的。

https://docs.soliditylang.org/en/latest/contracts.html?highlight=constructor#constructors

【讨论】:

【参考方案4】:

如果是返回地址数组,可以在返回address type之后声明memory

function getAllPlayers() public view returns(address[] memory)
        return players;
    

【讨论】:

以上是关于函数中返回参数的数据位置必须是“内存”,但没有给出的主要内容,如果未能解决你的问题,请参考以下文章

如何可靠地返回地址数组?

线程中的类型错误。函数接受 x 位置参数,但给出了 y

搜索文件时函数 main() 的参数

python-参数

带有指针参数的 C++ 函数

Day 18 函数之一