Solidity
如何在 Solidity 中對字節、字元串和數組進行切片?
是否可以在 Solidity 中對變數進行切片?
Solidity 0.6.0 及更高版本(2020 年更新)
從 Solidity 0.6.0 開始,Solidity 中內置了數組切片功能。語法類似於現有語言,因為數組採用以下參數
x[start:end]
。這裡,start
和end
是int
表示要切片的開始和結束索引的 s。如果
start
大於end
或end
大於數組的長度,則拋出異常。需要注意的是,
start
或者end
(或both
)可以從程式碼中排除。start
預設為 0,end
預設為數組的長度。在以下情況下:
start
被排除,返回值將是從索引0
到指定的切片數組end
end
被排除,返回值將是從指定start
索引到數組末尾的切片數組- 兩者都被省略,返回的數組將與輸入數組相同
例子
簡化範例
bytes exampleBytes = '0xabcd' exampleBytes[2:5]; # 'abc' exampleBytes[:5]; # '0xabc' exampleBytes[2:]; # 'abcd' exampleBytes[:]; # '0xabcd'
完整範例(來自 Solidity 文件)
pragma solidity ^0.6.0; contract Proxy { /// Address of the client contract managed by proxy i.e., this contract address client; constructor(address _client) public { client = _client; } /// Forward call to "setOwner(address)" that is implemented by client /// after doing basic validation on the address argument. function forward(bytes calldata _payload) external { bytes4 sig = abi.decode(_payload[:4], (bytes4)); if (sig == bytes4(keccak256("setOwner(address)"))) { address owner = abi.decode(_payload[4:], (address)); require(owner != address(0), "Address of owner cannot be zero."); } (bool status,) = client.delegatecall(_payload); require(status, "Forwarded call failed."); } }
注意:從 Solidity 0.6.0 開始,數組切片僅適用於 calldata 數組。
堅固性 < 0.6.0
對於 0.6.0 之前的 Solidity 版本,語言中沒有內置切片功能。但是,考慮到當時可用的語言特性,有一些方法可以執行類似的功能。
要切片 a
string
,您可以執行以下操作(來自此答案):pragma solidity 0.4.24; contract test{ function getSlice(uint256 begin, uint256 end, string text) public pure returns (string) { bytes memory a = new bytes(end-begin+1); for(uint i=0;i<=end-begin;i++){ a[i] = bytes(text)[i+begin-1]; } return string(a); } }
您還可以使用Arachnid (Nick Johnson)的 stringutils 庫來實現相同的目標。