#arrays #ethereum #solidity
#массивы #эфириум #прочность
Вопрос:
У меня есть два массива фиксированной длины, которые я хочу отправить в служебную функцию, но это приводит к следующей ошибке, так как длина массивов различна.
TypeError: Invalid type for argument in function call. Invalid implicit conversion from string storage ref[2] storage ref to string storage ref[] storage pointer requested.
Есть ли способ создать служебную функцию, которая будет принимать фиксированные массивы произвольной длины?
Полный фрагмент кода
contract test { string[2] internal list1 = ["str1", "str2"]; string[3] internal list2 = ["str3", "str4", "str5"]; function entryPoint() public view returns (uint256) { return utilityFunction(list1, list2); } function utilityFunction(string[] storage _list1, string[] storage _list2) internal pure returns (uint256 result) { // some logic here } }
Ответ №1:
Вы можете заставить функцию принимать предопределенную фиксированную длину
// changed `string[]` to `string[2]` and the other `string[]` to `string[3]` function utilityFunction(string[2] storage _list1, string[3] storage _list2) internal pure returns (uint256 result) {
Или вы можете сначала преобразовать массивы в динамический размер, а затем передать их в функцию приема динамического размера
function entryPoint() public view returns (uint256) { // declare a dynamic-size array in memory with 2 empty items string[] memory _list1 = new string[](2); // assign values to the dynamic-size array _list1[0] = list1[0]; _list1[1] = list1[1]; string[] memory _list2 = new string[](3); _list2[0] = list2[0]; _list2[1] = list2[1]; _list2[2] = list2[2]; // pass the dynamic-size in-memory arrays return utilityFunction(_list1, _list2); } // changed location to memory, now you can accept dynamic-size arrays with arbitrary length function utilityFunction(string[] memory _list1, string[] memory _list2) internal pure returns (uint256 result) { }
Но в настоящее время (v0.8) нет возможности принимать массивы фиксированного размера произвольной длины. Только с заданной длиной.
Примечание: В моем примере есть некоторое пространство для оптимизации газа entryPoint()
(сначала делая копии list1
и в памяти list2
, а затем считывая из копий в памяти при присвоении значений _list1
и _list2
). Но моя цель состояла в том, чтобы сделать более четкий пример назначения массиву динамического размера вместо ухудшения читаемости кода за счет оптимизации.