W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
狀態(tài)變量可以聲明為constant或immutable。在這兩種情況下,變量在合約構(gòu)建后都不能修改。對(duì)于constant變量,值必須在編譯時(shí)固定,而對(duì)于immutable,它仍然可以在構(gòu)造時(shí)賦值。
也可以constant在文件級(jí)別定義變量。
編譯器不會(huì)為這些變量保留存儲(chǔ)槽,每次出現(xiàn)都會(huì)被相應(yīng)的值替換。
與常規(guī)狀態(tài)變量相比,常量和不可變變量的 gas 成本要低得多。對(duì)于常量變量,分配給它的表達(dá)式被復(fù)制到所有訪問它的地方,并且每次都重新計(jì)算。這允許局部?jī)?yōu)化。不可變變量在構(gòu)造時(shí)被評(píng)估一次,它們的值被復(fù)制到代碼中訪問它們的所有位置。對(duì)于這些值,保留 32 個(gè)字節(jié),即使它們可以容納更少的字節(jié)。因此,常量值有時(shí)可能比不可變值便宜。
目前并非所有常量和不可變類型都已實(shí)現(xiàn)。唯一支持的類型是 字符串(僅用于常量)和值類型。
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.4; uint constant X = 32**22 + 8; contract C { string constant TEXT = "abc"; bytes32 constant MY_HASH = keccak256("abc"); uint immutable decimals; uint immutable maxBalance; address immutable owner = msg.sender; constructor(uint decimals_, address ref) { decimals = decimals_; // Assignments to immutables can even access the environment. maxBalance = ref.balance; } function isBalanceTooHigh(address other) public view returns (bool) { return other.balance > maxBalance; } }
對(duì)于constant
變量,該值在編譯時(shí)必須是一個(gè)常量,并且必須在聲明變量的地方賦值。任何訪問存儲(chǔ)、區(qū)塊鏈數(shù)據(jù)(例如block.timestamp
,address(this).balance
或 block.number
)或執(zhí)行數(shù)據(jù)(msg.value
或gasleft()
)或調(diào)用外部合約的表達(dá)式都是不允許的。允許可能對(duì)內(nèi)存分配產(chǎn)生副作用的表達(dá)式,但不允許對(duì)其他內(nèi)存對(duì)象產(chǎn)生副作用的表達(dá)式。允許使用內(nèi)置函數(shù) keccak256
、sha256
、ripemd160
、和 (盡管除了
之外ecrecover
,它們確實(shí)調(diào)用了外部合約)。addmod
mulmod
keccak256
允許對(duì)內(nèi)存分配器產(chǎn)生副作用的原因是應(yīng)該可以構(gòu)造復(fù)雜的對(duì)象,例如查找表。此功能尚未完全可用。
聲明為的變量immutable
比聲明為的變量的限制要少一些constant
:不可變變量可以在合約的構(gòu)造函數(shù)中或在它們的聲明點(diǎn)被分配一個(gè)任意值。它們只能分配一次,從那時(shí)起,即使在施工期間也可以讀取。
編譯器生成的合約創(chuàng)建代碼將在返回之前修改合約的運(yùn)行時(shí)代碼,將所有對(duì)不可變對(duì)象的引用替換為分配給它們的值。如果您將編譯器生成的運(yùn)行時(shí)代碼與實(shí)際存儲(chǔ)在區(qū)塊鏈中的運(yùn)行時(shí)代碼進(jìn)行比較,這一點(diǎn)很重要。
筆記
在聲明時(shí)分配的不可變對(duì)象僅在合約的構(gòu)造函數(shù)執(zhí)行后才被視為已初始化。這意味著您不能使用依賴于另一個(gè)不可變對(duì)象的值內(nèi)聯(lián)初始化不可變對(duì)象。但是,您可以在合約的構(gòu)造函數(shù)中執(zhí)行此操作。
這是為了防止對(duì)狀態(tài)變量初始化和構(gòu)造函數(shù)執(zhí)行順序的不同解釋,特別是在繼承方面。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: