摘要:還需注意的一點是,定長數組,不能與變長數組相互賦值,我們來看下面的代碼無法編譯已經計劃在未來移除這樣的限制。的變長數組,可以通過給賦值調整數組長度。的變長數組不支持。
本文首發于深入淺出區塊鏈社區
原文鏈接:智能合約語言Solidity教程系列5 - 數組介紹原文已更新,請讀者前往原文閱讀
Solidity 教程系列第5篇 - Solidity 數組介紹。
Solidity 系列完整的文章列表請查看分類-Solidity。
Solidity 是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所了解,
如果你還不了解,建議你先看以太坊是什么
本文前半部分是參考Solidity官方文檔(當前最新版本:0.4.20)進行翻譯,后半部分對官方文檔中沒有提供代碼的知識點補充代碼說明(訂閱專欄閱讀)。
數組(Arrays)數組可以聲明時指定長度,也可以是動態變長。對storage存儲的數組來說,元素類型可以是任意的,類型可以是數組,映射類型,結構體等。但對于memory的數組來說。如果作為public函數的參數,它不能是映射類型的數組,只能是支持ABI的類型。
一個元素類型為T,固定長度為k的數組,可以聲明為T[k],而一個動態大?。ㄗ冮L)的數組則聲明為T[]。
還可以聲明一個多維數組,如聲明一個類型為uint的數組長度為5的變長數組(5個元素都是變長數組),可以聲明為uint[][5]。(注意,相比非區塊鏈語言,多維數組的長度聲明是反的。)
要訪問第三個動態數組的第二個元素,使用x2。數組的序號是從0開始的,序號順序與定義相反。
bytes和string是一種特殊的數組。bytes類似byte[],但在外部函數作為參數調用中,bytes會進行壓縮打包。string類似bytes,但不提供長度和按序號的訪問方式(目前)。
所以應該盡量使用bytes而不是byte[]。
可以將字符串s通過bytes(s)轉為一個bytes,可以通過bytes(s).length獲取長度,bytes(s)[n]獲取對應的UTF-8編碼。通過下標訪問獲取到的不是對應字符,而是UTF-8編碼,比如中文編碼是多字節,變長的,所以下標訪問到的只是其中的一個編碼。創建內存數組
類型為數組的狀態變量,可以標記為public,從而讓Solidity創建一個訪問器,如果要訪問數組的某個元素,指定數字下標就好了。(稍后代碼事例)
可使用new關鍵字創建一個memory的數組。與stroage數組不同的是,你不能通過.length的長度來修改數組大小屬性。我們來看看下面的例子:
pragma solidity ^0.4.16; contract C { function f(uint len) public pure { uint[] memory a = new uint[](7); //a.length = 100; // 錯誤 bytes memory b = new bytes(len); // Here we have a.length == 7 and b.length == len a[6] = 8; } }數組常量及內聯數組
數組常量,是一個數組表達式(還沒有賦值到變量)。下面是一個簡單的例子:
pragma solidity ^0.4.16; contract C { function f() public pure { g([uint(1), 2, 3]); } function g(uint[3] _data) public pure { // ... } }
通過數組常量,創建的數組是memory的,同時還是定長的。元素類型則是使用剛好能存儲的元素的能用類型,比如[1, 2, 3],只需要uint8即可存儲,它的類型是uint8[3] memory。
由于g()方法的參數需要的是uint(默認的uint表示的其實是uint256),所以需要對第一個元素進行類型轉換,使用uint(1)來進行這個轉換。
還需注意的一點是,定長數組,不能與變長數組相互賦值,我們來看下面的代碼:
// 無法編譯 pragma solidity ^0.4.0; contract C { function f() public { // The next line creates a type error because uint[3] memory // cannot be converted to uint[] memory. uint[] x = [uint(1), 3, 4]; } }
已經計劃在未來移除這樣的限制。當前因為ABI傳遞數組還有些問題。
成員 length屬性數組有一個.length屬性,表示當前的數組長度。storage的變長數組,可以通過給.length賦值調整數組長度。memory的變長數組不支持。
不能通過訪問超出當前數組的長度的方式,來自動實現改變數組長度。memory數組雖然可以通過參數,靈活指定大小,但一旦創建,大小不可調整。
storage的變長數組和bytes都有一個push方法(string沒有),用于附加新元素到數據末端,返回值為新的長度。
限制情況當前在external函數中,不能使用多維數組。
另外,基于EVM的限制,不能通過外部函數返回動態的內容。
contract C { function f() returns (uint[]) { ... } }
在這個的例子中,如果通過web.js調用能返回數據,但從Solidity中調用不能返回數據。一種繞過這個問題的辦法是使用一個非常大的靜態數組。
pragma solidity ^0.4.16; contract ArrayContract { uint[2**20] m_aLotOfIntegers; // 這里不是兩個動態數組的數組,而是一個動態數組里,每個元素是長度為二的數組。 bool[2][] m_pairsOfFlags; // newPairs 存在 memory里,因為是函數參數 function setAllFlagPairs(bool[2][] newPairs) public { m_pairsOfFlags = newPairs; } function setFlagPair(uint index, bool flagA, bool flagB) public { // 訪問不存在的index會拋出異常 m_pairsOfFlags[index][0] = flagA; m_pairsOfFlags[index][1] = flagB; } function changeFlagArraySize(uint newSize) public { // 如果新size更小, 移除的元素會被銷毀 m_pairsOfFlags.length = newSize; } function clear() public { // 銷毀 delete m_pairsOfFlags; delete m_aLotOfIntegers; // 同銷毀一樣的效果 m_pairsOfFlags.length = 0; } bytes m_byteData; function byteArrays(bytes data) public { // byte arrays ("bytes") are different as they are stored without padding, // but can be treated identical to "uint8[]" m_byteData = data; m_byteData.length += 7; m_byteData[3] = byte(8); delete m_byteData[2]; } function addFlag(bool[2] flag) public returns (uint) { return m_pairsOfFlags.push(flag); } function createMemoryArray(uint size) public pure returns (bytes) { // Dynamic memory arrays are created using `new`: uint[2][] memory arrayOfPairs = new uint[2][](size); // Create a dynamic byte array: bytes memory b = new bytes(200); for (uint i = 0; i < b.length; i++) b[i] = byte(i); return b; } }補充事例說明
事例代碼及講解,請訂閱區塊鏈技術查看。
參考視頻我們也推出了目前市面上最全的視頻教程:深入詳解以太坊智能合約語言Solidity
目前我們也在招募體驗師,可以點擊鏈接了解。
Solidity官方文檔-數組
? 深入淺出區塊鏈 - 系統學習區塊鏈,打造最好的區塊鏈技術博客。
? 我的知識星球為各位解答區塊鏈技術問題,歡迎加入討論。
? 關注公眾號“深入淺出區塊鏈技術”第一時間獲取區塊鏈技術信息。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/24091.html
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列地址類型介紹原文已更新,請讀者前往原文閱讀現在的中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。枚舉類型應至少有一名成員。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列2 - 地址類型介紹原文已更新,請讀者前往原文閱讀 現在的Solidity中文文檔,要么翻譯的太爛,要么太舊,決定重新翻譯下。...
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列錯誤處理原文已更新,請讀者前往原文閱讀這是教程系列文章第篇介紹錯誤處理。如果合約沒有修飾符的的函數在接收以太幣時包括構造函數,和回退函數。如果合約通過一個的函數接收以太幣。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列9 - 錯誤處理原文已更新,請讀者前往原文閱讀 這是Solidity教程系列文章...
摘要:狀態變量合約內聲明的公有變量還有一個存儲位置是,用來存儲函數參數,是只讀的,不會永久存儲的一個數據位置。稱這個為狀態改變,這也是合約級變量稱為狀態變量的原因。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言 Solidity 教程系列4 - 數據存儲位置分析原文已更新,請讀者前往原文閱讀 Solidity教程系列第4篇 - Solidity數據位置分析。 寫在前面 Solidity...
摘要:本文首發于深入淺出區塊鏈社區原文鏈接智能合約語言教程系列結構體與映射原文已更新,請讀者前往原文閱讀教程系列第篇結構體與映射。不能聲明一個同時將自身作為成員,這個限制是基于結構體的大小必須是有限的。 本文首發于深入淺出區塊鏈社區原文鏈接:智能合約語言Solidity教程系列6 - 結構體與映射原文已更新,請讀者前往原文閱讀 Solidity 教程系列第6篇 - Solidity 結構體與...
閱讀 814·2023-04-25 20:18
閱讀 2097·2021-11-22 13:54
閱讀 2536·2021-09-26 09:55
閱讀 3898·2021-09-22 15:28
閱讀 2978·2021-09-03 10:34
閱讀 1713·2021-07-28 00:15
閱讀 1635·2019-08-30 14:25
閱讀 1284·2019-08-29 17:16