W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
在某些情況下,編譯器會在賦值期間、將參數(shù)傳遞給函數(shù)以及應用運算符時自動應用隱式類型轉換。一般來說,如果在語義上有意義并且沒有信息丟失,則值類型之間的隱式轉換是可能的。
例如,uint8
可轉換為 uint16
和int128
,int256
但int8
不可轉換為uint256
,因為uint256
不能保存諸如 之類的值-1
。
如果將運算符應用于不同的類型,編譯器會嘗試將其中一個操作數(shù)隱式轉換為另一個操作數(shù)的類型(賦值也是如此)。這意味著操作總是以操作數(shù)之一的類型執(zhí)行。
有關可以進行哪些隱式轉換的更多詳細信息,請參閱有關類型本身的部分。
在下面的示例中,加法的操作數(shù)y
和z
不具有相同的類型,但uint8
可以隱式轉換為uint16
,反之亦然。因此, 在類型中執(zhí)行加法之前y
轉換為類型。表達式的結果類型是。因為它被分配給類型的變量,所以在添加之后執(zhí)行另一個隱式轉換。z
uint16
y + z
uint16
uint32
uint8 y; uint16 z; uint32 x = y + z;
如果編譯器不允許隱式轉換,但您確信轉換會起作用,則有時可以進行顯式類型轉換。這可能會導致意外行為并允許您繞過編譯器的某些安全功能,因此請務必測試結果是否符合您的要求!
舉一個將負數(shù)轉換為 a 的int
示例uint
:
int y = -3; uint x = uint(y);
在此代碼片段的末尾,x
將具有值0xfffff..fd
(64 個十六進制字符),在 256 位的二進制補碼表示中為 -3。
如果將整數(shù)顯式轉換為更小的類型,則高階位被截斷:
uint32 a = 0x12345678; uint16 b = uint16(a); // b will be 0x5678 now
如果一個整數(shù)被顯式轉換為一個更大的類型,它會被填充到左邊(即在高階端)。轉換的結果將等于原始整數(shù):
uint16 a = 0x1234; uint32 b = uint32(a); // b will be 0x00001234 now assert(a == b);
固定大小的字節(jié)類型在轉換過程中表現(xiàn)不同。它們可以被認為是單個字節(jié)的序列,轉換為更小的類型將切斷序列:
bytes2 a = 0x1234; bytes1 b = bytes1(a); // b will be 0x12
如果將固定大小的字節(jié)類型顯式轉換為更大的類型,則會在右側填充。訪問固定索引處的字節(jié)將導致轉換前后的值相同(如果索引仍在范圍內(nèi)):
bytes2 a = 0x1234; bytes4 b = bytes4(a); // b will be 0x12340000 assert(a[0] == b[0]); assert(a[1] == b[1]);
由于整數(shù)和固定大小的字節(jié)數(shù)組在截斷或填充時表現(xiàn)不同,因此僅允許整數(shù)和固定大小的字節(jié)數(shù)組之間的顯式轉換,前提是兩者具有相同的大小。如果要在整數(shù)和不同大小的固定大小字節(jié)數(shù)組之間進行轉換,則必須使用中間轉換來明確所需的截斷和填充規(guī)則:
bytes2 a = 0x1234; uint32 b = uint16(a); // b will be 0x00001234 uint32 c = uint32(bytes4(a)); // c will be 0x12340000 uint8 d = uint8(uint16(a)); // d will be 0x34 uint8 e = uint8(bytes1(a)); // e will be 0x12
bytes
數(shù)組和bytes
calldata 切片可以顯式轉換為固定字節(jié)類型(bytes1
/…/ bytes32
)。如果數(shù)組比目標固定字節(jié)類型長,最后會發(fā)生截斷。如果數(shù)組比目標類型短,則將在末尾用零填充。
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.5; contract C { bytes s = "abcdefgh"; function f(bytes calldata c, bytes memory m) public view returns (bytes16, bytes3) { require(c.length == 16, ""); bytes16 b = bytes16(m); // if length of m is greater than 16, truncation will happen b = bytes16(s); // padded on the right, so result is "abcdefgh\0\0\0\0\0\0\0\0" bytes3 b1 = bytes3(s); // truncated, b1 equals to "abc" b = bytes16(c[:8]); // also padded with zeros return (b, b1); } }
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: