数组字面量(Array Literals),是以一个逗号分隔的列表,包含一个或多个表达式,用方括号括起来([…])。例如[1,a, f(3)]。
数组字面量的类型确定,它总是一个静态大小的内存数组,其长度为表达式的数量。数组的基类型是列表中第一个表达式的类型,以便所有其他表达式都可以隐式地转换为它。
在下面的例子中,[1,2,3]的类型是 uint8[3] memory,因为这些常量的类型都是uint8。如果您希望结果是一个uint[3] memory 类型,您需要将第一个元素显式转换为uint。
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract C {
function f() public pure {
g([1, 2, 3]);
}
function g(uint[3] memory) public pure {
// ...
}
}
编译报错:
?修改方法: g([uint(1),?2,?3]);
数组字面量[1,-1]是无效的,因为第一个表达式的类型是uint8,而第二个表达式的类型是int8,它们不能隐式地相互转换。所以要使它编译通过,可以使用[int8(1), -1]。
固定大小的内存数组不能赋值给动态大小的内存数组,也就是说,以下情况是不可能的:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
// This will not compile.
contract C {
function f() public {
// The next line creates a type error because uint[3] memory
// cannot be converted to uint[] memory.
uint[] memory x = [uint(1), 3, 4];
}
}
由于在ABI中传递数组的方式,这会造成一些复杂性。 所以官方计划在将来消除这一限制。
?如果你想初始化动态大小的数组,你必须为每个元素赋值:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract C {
function f() public pure {
uint[] memory x = new uint[](3);
x[0] = 1;
x[1] = 3;
x[2] = 4;
}
}
由于不同类型的固定大小内存数组不能相互转换(即使基类型可以),如果你想使用二维数组字面量,你总是必须显式指定一个通用的基类型:(这段话不是很理解,希望博友们发表些见解)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract C {
function f() public pure returns (uint24[2][4] memory) {
uint24[2][4] memory x = [[uint24(0x1), 1], [0xffffff, 2], [uint24(0xff), 3], [uint24(0xffff), 4]];
// The following does not work, because some of the inner arrays are not of the right type.
// uint[2][4] memory x = [[0x1, 1], [0xffffff, 2], [0xff, 3], [0xffff, 4]];
return x;
}
}
最后普及个小知识,字面量(Literals)一词在技术类文档中也是频繁出现的,乍一看蛮高大尚的名词,网上搜索的结果大都语焉不详。引用MDN的原文来解释吧:
Literals represent values in JavaScript. These are fixed values—not variables—that you literally provide in your script.
可能光看还是不太理解,没关系,理论结合程序你就茅塞顿开了:
uint age = 20;
string name = "jack";
address myAddr = 0x583031D1113aD414F02576BD6afaBfb302140225;
等号的左边都是变量(age、name、myAddr),而右边的都是字面量(20,jack......),也就是说字面量是你在程序源码中直接写出来的值,即字面上的值。
|