中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

solidity表達式和控制結構怎么使用

發布時間:2021-12-07 15:56:18 來源:億速云 閱讀:145 作者:iii 欄目:互聯網科技

本篇內容介紹了“solidity表達式和控制結構怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

表達式和控制結構

控制結構

除了 switch和goto,solidity的絕大多數控制結構均來自于C / JavaScript,if, else, while, for, break, continue, return, ? :, 的語義均和C / JavaScript一樣。

條件語句中的括號不能省略,但在單條語句前后的花括號可以省略。

注意,(Solidity中 )沒有象C和JavaScrip那樣 ,從非布爾類型類型到布爾類型的轉換,  所以if (1){…}不是合法的Solidity(語句)。

函數調用

內部函數調用

當前合約和函數可以直接調用(“內部”),也可以遞歸, 所以你會看到在這個“荒謬”的例子:

contract c {

  function g(uint a) returns (uint ret) { return f(); }

  function f() returns (uint ret) { return g(7) + f(); }}

這些函數調用在EMV里翻譯成簡單的jumps 語句。當前內存沒有被清除,  即通過內存引用的函數是非常高效的。僅僅同一個合約的函數可在內部被調用。

外部函數調用

表達式this.g(8);也是一個合法的函數調用,  但是這一次,這個函數將被稱為“外部”的, 通過消息調用,而不是直接通過jumps調用。其他合約的函數也是外部調用。對于外部調用,所有函數參數必須被復制到內存中。

當調用其他合約的函數時, 這個調用的wei的數量被發送和gas被定義:

contract InfoFeed {

  function info() returns (uint ret) { return 42; }

}

contract Consumer {

  InfoFeed feed;

  function setFeed(address addr) { feed = InfoFeed(addr); }

  function callFeed() { feed.info.value(10).gas(800)(); }

}

注意:表達式InfoFeed(addr)執行顯式的類型轉換, 意思是“我們知道給定的地址的合約類型是InfoFeed”, 這并不執行構造函數。 我們也可以直接使用函數setFeed(InfoFeed _feed) { feed = _feed; }。 注意: feed.info.value(10).gas(800)是(本地)設置值和函數調用發送的gas數量, 只有最后的括號結束后才完成實際的調用。

具名調用和匿名函數參數

有參數的函數調用可以有名字,不使用參數的名字(特別是返回參數)可以省略。

contract c {

  function f(uint key, uint value) { ... }

  function g() {

    // named arguments   具名參數

    f({value: 2, key: 3});

  }

  // omitted parameters 省略名字的參數

  function func(uint k, uint) returns(uint) {

    return k;

  }

}

表達式計算的次序

表達式的計算順序是不確定的(準確地說是, 順序表達式樹中的子節點表達式計算順序是不確定的的, 但他們對節點本身,計算表達式順序當然是確定的)。只保證語句執行順序,以及布爾表達式的短路規則。

賦值

析構賦值并返回多個值

Solidity內部允許元組類型,即一系列的不同類型的對象的大小在編譯時是一個常量。這些元組可以用來同時返回多個值,并且同時將它們分配給多個變量(或左值運算)

contract C {

  uint[] data;

  function f() returns (uint, bool, uint) {

    return (7, true, 2);

  }

  function g() {

    // Declares and assigns the variables. Specifying the type explicitly is not possible.

    var (x, b, y) = f();

    // Assigns to a pre-existing variable.

    (x, y) = (2, 7);

    // Common trick to swap values -- does not work for non-value storage types.

    (x, y) = (y, x);

    // Components can be left out (also for variable declarations).

    // If the tuple ends in an empty component,

    // the rest of the values are discarded.

    (data.length,) = f(); // Sets the length to 7

    // The same can be done on the left side.

    (,data[3]) = f(); // Sets data[3] to 2

    // Components can only be left out at the left-hand-side of assignments, with

    // one exception:

    (x,) = (1,);

    // (1,) is the only way to specify a 1-component tuple, because (1) is

    // equivalent to 1.

  }

}

contract C {

  uint[] data;

  function f() returns (uint, bool, uint) {

    return (7, true, 2);

  }

  function g() {

    // Declares and assigns the variables. Specifying the type explicitly is not possible. 聲明和賦值變量,不必顯示定義類型

    var (x, b, y) = f();

    // Assigns to a pre-existing variable. 賦值給已經存在的變量

    (x, y) = (2, 7);

    // Common trick to swap values -- does not work for non-value storage types. 交換值的技巧-對非值存儲類型不起作用

    (x, y) = (y, x);

    // Components can be left out (also for variable declarations). 元素可排除(對變量聲明也適用)

    // If the tuple ends in an empty component, 如果元組是以空元素為結尾

    // the rest of the values are discarded.  值的其余部分被丟棄

    (data.length,) = f(); // Sets the length to 7 設定長度為7

    // The same can be done on the left side. 同樣可以在左側做

    (,data[3]) = f(); // Sets data[3] to 2  將data[3] 設為2

    // Components can only be left out at the left-hand-side of assignments, with

    // one exception:    組件只能在賦值的左邊被排除,有一個例外

    (x,) = (1,);

    // (1,) is the only way to specify a 1-component tuple, because (1) is     (1,)是定義一個元素的元組,(1)是等于1

    // equivalent to 1.

  }}

數組和結構體的組合

對于象數組和結構體這樣的非值類型,賦值的語義更復雜些。賦值到一個狀態變量總是需要創建一個獨立的副本。另一方面,對基本類型來說,賦值到一個局部變量需要創建一個獨立的副本, 即32字節的靜態類型。如果結構體或數組(包括字節和字符串)從狀態變量被賦值到一個局部變量,  局部變量則保存原始狀態變量的引用。第二次賦值到局部變量不修改狀態,只改變引用。賦值到局部變量的成員(或元素)將改變狀態。

異常

有一些自動拋出異常的情況(見下文)。您可以使用throw 指令手動拋出一個異常。異常的影響是當前執行的調用被停止和恢復(即所有狀態和余額的變化均沒有發生)。另外, 異常也可以通過Solidity 函數 “冒出來”, (一旦“異常”發生, 就send "exceptions", call和callcode底層函數就返回false)。

捕獲異常是不可能的。

在接下來的例子中,我們將演示如何輕松恢復一個Ether轉移,以及如何檢查send的返回值:

contract Sharer {

    function sendHalf(address addr) returns (uint balance) {

        if (!addr.send(msg.value/2))

            throw; // also reverts the transfer to Sharer

        return this.balance;

    }

}

contract Sharer {

    function sendHalf(address addr) returns (uint balance) {

        if (!addr.send(msg.value/2))

            throw; // also reverts the transfer to Sharer  也恢復Sharer的轉移

        return this.balance;

    }

}

目前,Solidity異常自動發生,有三種情況, :

  1. 如果你訪問數組超出其長度 (即x[i] where i >= x.length)

  2. 如果一個通過消息調用的函數沒有正確的執行結束(即gas用完,或本身拋出異常)。

  3. 如果一個庫里不存在的函數被調用,或Ether被發送到一個函數庫里。

在內部,當拋出異常時 ,Solidity就執行“非法jump”, 從而導致EMV(Ether虛擬機)恢復所有更改狀態。這個原因是沒有安全的方法可以繼續執行,   預期的結果沒有發生。由于我們想保留事務的原子性,(所以)最安全的做法是恢復所有更改,并使整個事務(或者至少調用)沒有受影響。

“solidity表達式和控制結構怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

马山县| 大洼县| 凤台县| 马关县| 涟源市| 青岛市| 阿城市| 乌鲁木齐县| 吉林省| 香格里拉县| 蕲春县| 兴和县| 南召县| 河北省| 孝感市| 荔波县| 浮山县| 宣恩县| 罗田县| 巴青县| 江山市| 奉节县| 兴安盟| 芮城县| 邯郸市| 河西区| 泰和县| 巴彦淖尔市| 枣庄市| 洛隆县| 若羌县| 三都| 曲松县| 罗江县| 麻江县| 南丹县| 万盛区| 武川县| 勐海县| 乌拉特前旗| 台湾省|