是否有固态数组的弹出功能?

Sur*_*hli 5 data-structures solidity

我已经使用solidity将数据推送到数组中.pop有类似的功能吗?

string[] myArray;
myArray.push("hello")
Run Code Online (Sandbox Code Playgroud)

什么是最好的解决方案?如何在稳定性中删除动态数组中的元素?

Ada*_*nis 6

更新2-19-2019:正如Joel在下面指出的那样,pop已添加到内置阵列支持中.请参阅https://solidity.readthedocs.io/en/v0.5.4/types.html#array-members.留下原始答案,以防其他人使用旧版本的Solidity.


Solidity中没有pop功能.您可以考虑使用几个选项来维护阵列.

删除并留下空白

最简单的解决方案是仅delete使用特定索引处的元素:

string element = myArray[index];
delete myArray[index];
return element;
Run Code Online (Sandbox Code Playgroud)

但是,这不会移动数组中的元素,并且会在数组中留下"string 0"元素.要检查此元素,您可以使用

if(bytes(myArray[index]).length > 0) ...

交换和删除

如果您不关心数组中的顺序,可以将元素与数组中的最后一个元素交换,然后删除:

string element = myArray[index];
myArray[index] = myArray[myArray.length - 1];
delete myArray[myArray.length - 1];
myArray.length--;
return element;
Run Code Online (Sandbox Code Playgroud)

使用Shift删除

如果数组中的顺序很重要,则可以删除该元素,然后将所有剩余元素移到左侧.

string element = myArray[index];
for (uint i = index; i < myArray.length - 1; i++) {
  myArray[index] = myArray[index + 1];
}
delete myArray[myArray.length - 1];
myArray.length--;
return element;
Run Code Online (Sandbox Code Playgroud)

请注意,这将是最昂贵的选项.如果您的阵列很长,您的天然气使用量很高.

与@ Jedsada的建议相关,这是一个作为库的版本:

pragma solidity ^0.4.24;

library StackLib {
  using StackLib for Stack;

  struct Stack {
    uint[] _items;
  }

  function pushElement(Stack storage self, uint element) internal returns (bool) {
    self._items.push(element);
  }

  function popElement(Stack storage self) internal returns (uint) {
    uint element = self.peek();

    if (self.size() > 0)
      delete self._items[self.size() - 1];

    return element;
  }

  function peek(Stack storage self) internal returns (uint) {
    uint value;

    if (self.size() > 0)
      value = self._items[self.size() - 1];

    return value;
  }

  function size(Stack storage self) internal returns (uint8) {
    return self.size();
  }
}
Run Code Online (Sandbox Code Playgroud)

示例用法(重要说明:您不能使用popElement并将值返回给客户端.该方法更改状态,只应在事务中使用.):

contract Test {
  using StackLib for StackLib.Stack;

  StackLib.Stack numbers;

  function add(uint v) public {
    numbers.pushElement(v);
  }

  function doSomething() public {
    for (uint8 i = 0; i < numbers.size(); i++) {
      uint curNum = numbers.popElement();

      // do something with curNum
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

附加说明:遗憾的是,var自0.4.20以来已被弃用,并且没有替代泛型.您必须为特定类型进行自定义.