操作符

2022-05-12 17:01 更新

即使兩個操作數的類型不同,也可以應用算術和位運算符。例如,您可以計算:y = x + z,其中x是 uint8并且z類型為int32。在這些情況下,將使用以下機制來確定計算運算的類型(這在溢出的情況下很重要)和運算符結果的類型:

  1. 如果右操作數的類型可以隱式轉換為左操作數的類型,則使用左操作數的類型,
  2. 如果左操作數的類型可以隱式轉換為右操作數的類型,則使用右操作數的類型,
  3. 否則,該操作是不允許的。

如果其中一個操作數是文字數字,則首先將其轉換為其“移動類型”,這是可以保存該值的最小類型(相同位寬的無符號類型被認為比有符號類型“更小”) . 如果兩者都是文字數字,則以任意精度計算操作。

運算符的結果類型與執(zhí)行運算的類型相同,但結果始終為? bool?的比較運算符除外。

運算符**(取冪),<< 并>>使用左操作數的類型進行運算和結果。

三元運算符

三元運算符用于?<expression> ? <trueExpression> : <falseExpression>? 形式的表達式。它根據 main <expression>的評估結果評估后兩個給定表達式之一。如果評估為true,則將被評估<trueExpression>,否則將被評估<falseExpression>。

三元運算符的結果沒有有理數類型,即使它的所有操作數都是有理數文字。結果類型由兩個操作數的類型以與上述相同的方式確定,如果需要,首先轉換為它們的移動類型。

結果,將由于算術溢出而恢復。原因是is of type ,它也強制執(zhí)行加法,并且 256 超出了該類型允許的范圍。255 + (true ? 1 : 0)(true ? 1 : 0)uint8uint8

另一個結果是表達式 like是有效的,但不是。這是因為前者是一個無限精確計算的有理表達式,只有它的最終值才重要。后者涉及將小數有理數轉換為整數,目前是不允許的。1.5 + 1.51.5 + (true ? 1.5 : 2.5)

復合和遞增/遞減運算符

如果a是一個 LValue(即一個變量或可以賦值的東西),以下運算符可用作簡寫:

a += e相當于。運算符, , , , , , ,和相應定義。和等價于/但表達式本身仍然具有. 反之,和有同樣的效果,但返回改變后的值。a = a + e-=*=/=%=|=&=^=<<=>>=a++a--a += 1a -= 1a--a++aa

刪除

delete a將類型的初始值分配給a。即對于整數,它等價于,但它也可用于數組,其中它分配長度為零的動態(tài)數組或相同長度的靜態(tài)數組,所有元素都設置為其初始值。刪除數組索引處的項目,并保留所有其他元素和數組的長度不變。這尤其意味著它會在陣列中留下空隙。如果您打算刪除項目,映射可能是更好的選擇。a = 0delete a[x]x

對于結構,它分配一個所有成員都重置的結構。換句話說,aafter的值與在沒有賦值的情況下聲明if 的值相同,但需要注意以下幾點:delete aa

delete對映射沒有影響(因為映射的鍵可能是任意的并且通常是未知的)。因此,如果您刪除一個結構,它將重置所有不是映射的成員,并且還會遞歸到成員中,除非它們是映射。但是,可以刪除單個鍵及其映射的內容:如果a是映射,則將刪除存儲在的值。delete a[x]x

需要注意的是,它的行為實際上類似于對 的賦值,即它在 中存儲了一個新對象。當引用變量時,這種區(qū)別是可見的:它只會重置自己,而不是之前引用的值。delete aaaaa

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

contract DeleteExample {
    uint data;
    uint[] dataArray;

    function f() public {
        uint x = data;
        delete x; // sets x to 0, does not affect data
        delete data; // sets data to 0, does not affect x
        uint[] storage y = dataArray;
        delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
        // y is affected which is an alias to the storage object
        // On the other hand: "delete y" is not valid, as assignments to local variables
        // referencing storage objects can only be made from existing storage objects.
        assert(y.length == 0);
    }
}
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號