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

ven*_*s12 15 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 31

您应该为 string 参数添加 memory 关键字,这是在 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅有关 0.5.0 版中的重大更改的官方文档


Ahm*_*yeb 5

引用类型的值可以通过多个不同的名称进行修改。将此与值类型进行对比,其中每当使用值类型的变量时都会获得独立的副本。因此,必须比值类型更仔细地处理引用类型。目前,引用类型包括结构、数组和映射。如果使用引用类型,则始终必须明确提供存储该类型的数据区域:内存(其生命周期仅限于外部函数调用)、存储(存储状态变量的位置,生命周期为限于合约的生命周期)或 calldata(包含函数参数的特殊数据位置)。

Warning

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

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

所以你必须把memory或放在calldata 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";
    }
}
Run Code Online (Sandbox Code Playgroud)

另一件事要注意,您不必再将 public 放入构造函数中:

警告:在 0.7.0 版本之前,您必须将构造函数的可见性指定为内部或公共。

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