函数中返回参数的数据位置必须为“内存”,但未指定任何位置

时间:2019-10-06 15:39:37

标签: blockchain ethereum solidity

我在remix中尝试了如上所述的Solidity示例,solidity版本> 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";
    }
}

3 个答案:

答案 0 :(得分:4)

您应该为solid参数版本0.5.0中引入的字符串参数添加memory关键字

根据文档:

  

结构,数组或映射类型的所有变量的显式数据位置现在是必需的。这也适用于函数参数和返回变量。例如,将uint [] x = m_x更改为uint [] storage x = m_x,并将函数f(uint [] [] x)更改为函数f(uint [] [] memory x),其中memory是数据位置,并且可能相应地由存储或调用数据代替。请注意,外部函数要求参数的数据位置为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";
    }
}

有关在0.5.0版中所做的重大更改,请参考官方documentation

答案 1 :(得分:4)

<块引用>

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

Warning

<块引用>

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

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

所以你必须把 memorycalldata 放在 String 之后,如下所示:

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

答案 2 :(得分:0)

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

OR

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