【问题标题】: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";
    }
}

【问题讨论】:

    标签: blockchain ethereum solidity


    【解决方案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;
              }
          

          【讨论】:

            猜你喜欢
            • 2019-04-26
            • 1970-01-01
            • 2019-04-26
            • 1970-01-01
            • 2017-05-08
            • 1970-01-01
            • 1970-01-01
            • 2019-09-13
            • 2016-06-05
            相关资源
            最近更新 更多