从版本 0.6.0 开始,Solidity 支持数组切片。 数组切片 在您想要引用数组的连续部分但不想执行该部分的完整复制时非常有用。 目前,数组切片仅支持 calldata 数组。
如何使用数组切片
表达式x[start:end] 引用 calldata 数组 x 的一部分,从索引 start 开始,到索引 end 之前结束。
start 和 end 都是可选的。 如果未提供,start 默认为 0,end 默认为相应数组的长度。
请注意,不会执行从 calldata 到内存的复制操作。
您可以在变量上使用切片语法,也可以在 msg.data 上使用。
数组切片在与 abi.decode 结合使用时尤其有用,在回退函数:
pragma solidity ^0.6.5; interface OtherContract { function changeOwner(address) external; } contract Proxy { OtherContract implementation; address badOwner; fallback() external { if (msg.sig == OtherContract.changeOwner.selector) { // Here, abi.decode directly operates on the calldata array slice. address newOwner = abi.decode(msg.data[4:], (address)); require(newOwner != badOwner); } (bool success,) = address(implementation).delegatecall(msg.data); require(success); } }
数组切片在内部的工作原理
Calldata 数组一直由两个值表示:一个起始指针和一个长度值。 这与我们用于 calldata 数组切片的表示方式完全相同。
限制和未来计划
数组切片与数组一样支持索引访问和 .length,但不支持大多数复制操作。
目前,数组切片仅针对 calldata 实现。