Solidity語法詳解 - 類型介紹1

現在的Solidity中文文檔,要麼翻譯的太爛,要麼太舊,決定重新翻譯下。

尤其點名批評極客學院名為《Solidity官方文檔中文版》的翻譯,機器翻譯的都比它好,大家還是別看了。

寫在前面

Solidity是以太坊智能合約編程語言,閱讀本文前,你應該對以太坊、智能合約有所了解,如果你還不知道這些概念歡迎訂閱專欄:[區塊鏈技術](xiaozhuanlan.com/blockc)

Solidity語法的介紹會是一系列文章,本文是第一篇:介紹Solidity的變數類型。

全部系列文章地址:

深入淺出區塊鏈learnblockchain.cn

本文前半部分是參考Solidity官方文檔(當前最新版本:0.4.20)進行翻譯,前半部分是實際合約代碼實例說明類型的使用(僅針對[專欄](xiaozhuanlan.com/blockc)訂閱用戶)。

類型

Solidity是一種靜態類型語言,意味著每個變數(本地或狀態變數)需要在編譯時指定變數的類型(或至少可以推倒出類型)。Solidity提供了一些基本類型可以用來組合成複雜類型。

Solidity類型分為兩類:

* 值類型(Value Type) - 變數在賦值或傳參是,總是進行值拷貝。

* 引用類型(Reference Types)

值類型(Value Type)

**值類型**包含:

* 布爾類型(Booleans)

* 整型(Integers)

* 定長浮點型(Fixed Point Numbers)

* 定長位元組數組(Fixed-size byte arrays)

* 有理數和整型常量(Rational and Integer Literals)

* 字元串常量(String literals)

* 十六進位常量(Hexadecimal literals)

* 枚舉(Enums)

* 函數(Function Types)

* 地址(Address)

* 地址常量(Address Literals)

> 函數和地址講解會在之後的文章。

布爾類型(Booleans)

**布爾(bool)**:可能的取值為常量值**true****false**

布爾類型支持的運算符有:

* !邏輯非

* && 邏輯與

* || 邏輯或

* == 等於

* != 不等於

注意:運算符**&&****||**是短路運算符,如f(x)||g(y),當f(x)為真時,則不會繼續執行g(y)。

整型(Integers)

**int**/**uint**: 表示有符號和無符號不同位數整數。支持關鍵字**uint8****uint256** (以8步進),

**uint****int** 默認對應的是 **uint256****int256**

支持的運算符:

* 比較運算符: <=, < , ==, !=, >=, > (返回布爾值:true 或 false)

* 位操作符: &,|,^(異或),~(位取反)

* 算術操作符:+,-,一元運算-,一元運算+,*,/, %(取餘數), ***(冪), << (左移位), >>(右移位)

說明:

1. 整數除法總是截斷的,但如果運算符是字面量(字面量稍後講),則不會截斷。

2. 整數除0會拋異常。

3. 移位運算的結果的正負取決於操作符左邊的數。x << y 和 x * 2***y 是相等, x >> y 和 x / 2**y 是相等的。

4. 不能進行負移位,即操作符右邊的數不可以為負數,否則會拋出運行時異常。

注意:Solidity中,右移位是和除等價的,因此右移位一個負數,向下取整時會為0,而不像其他語言里為無限負小數。

定長浮點型(Fixed Point Numbers)

注意:定長浮點型 Solidity(發文時)還不完全支持,它可以用來聲明變數,但不可以用來賦值。

**fixed**/**ufixed**: 表示有符號和無符號的固定位浮點數。關鍵字為**ufixedMxN****ufixedMxN**

**M**表示這個類型要佔用的位數,以8步進,可為8到256位。

**N**表示小數點的個數,可為0到80之前

支持的運算符:

* 比較運算符: <=, < , ==, !=, >=, > (返回布爾值:true 或 false)

* 算術操作符:+,-,一元運算-,一元運算+,*,/, %(取餘數)

注意:它和大多數語言的float和double不一樣,**M**是表示整個數佔用的固定位數,包含整數部分和小數部分。因此用一個小位數(M較小)來表示一個浮點數時,小數部分會幾乎佔用整個空間。

定長位元組數組(Fixed-size byte arrays)

關鍵字有:bytes1, bytes2, bytes3, ..., bytes32。(以步長1遞增)

byte代表bytes1。

支持的運算符:

* 比較符: <=, <, ==, !=, >=, > (返回bool)

* 位操作符: &, |, ^ (按位異或),~(按位取反), << (左移位), >> (右移位)

* 索引(下標)訪問: 如果x是bytesI,當0 <= k < I ,則x[k]返回第k個位元組(只讀)。

移位運算和整數類似,移位運算的結果的正負取決於操作符左邊的數,且不能進行負移位。

成員變數:

**.length**:表示這個位元組數組的長度(只讀)。

## 變長(動態分配大小)位元組數組(Dynamically-sized byte array)

* bytes:動態分配大小位元組數組, 參見[Arrays](solidity.readthedocs.io),不是值類型!

* string:動態分配大小UTF8編碼的字元類型,參看[Arrays](solidity.readthedocs.io)。不是值類型!

根據經驗:

bytes用來存儲任意長度的位元組數據,string用來存儲任意長度的(UTF-8編碼)的字元串數據。

如果長度可以確定,盡量使用定長的如byte1到byte32中的一個,因為這樣更省空間。

有理數和整型常量(Rational and Integer Literals)

> 也有人把Literals翻譯為字面量

整型常量是有一系列0-9的數字組成,10進位表示,比如:8進位是不存在的,前置0在Solidity中是無效的。

10進位小數常量(Decimal fraction literals)帶了一個**.**, 在**.**的兩邊至少有一個數字,有效的表示如:**1.**, **.1****1.3**.

科學符號也支持,基數可以是小數,指數必須是整數, 有效的表示如: **2e10**, **-2e10**, **2e-10**, **2.5e1**

數字常量表達式本身支持任意精度,也就是可以不會運算溢出,或除法截斷。但當它被轉換成對應的非常量類型,或者將他們與非常量進行運算,則不能保證精度了。

如:(2***800 + 1) - 2***800的結果為1(uint8整類) ,儘管中間結果已經超過計算機字長。另外:**.5 * 8**的結果是4,儘管有非整形參與了運算。

只要操作數是整形,整型支持的運算符都適用於整型常量表達式。

如果兩個操作數是小數,則不允許進行位運算,指數也不能是小數。

注意:

Solidity對每一個有理數都有一個數值常量類型。整數常量和有理數常量從屬於數字常量。所有的數字常表達式的結果都屬於數字常量。所以1 + 2和2 + 1都屬於同樣的有理數的數字常量3

警告:

整數常量除法,在早期的版本中是被截斷的,但現在可以被轉為有理數了,如5/2的值為 2.5

注意:

數字常量表達式,一旦其中含有常量表達式,它就會被轉為一個非常量類型。下面代碼中表達式的結果將會被認為是一個有理數:

```

uint128 a = 1;

uint128 b = 2.5 + a + 0.5;

```

上述代碼編譯不能通過,因為b會被編譯器認為是小數型。

字元串常量

字元串常量是指由單引號,或雙引號引起來的字元串 ("foo" or bar)。字元串並不像C語言,包含結束符,"foo"這個字元串大小僅為三個位元組。和整數常量一樣,字元串的長度類型可以是變長的。字元串可以隱式的轉換為byte1,...byte32 如果適合,也會轉為bytes或string。

字元串常量支持轉義字元,比如
,xNN,uNNNN。其中xNN表示16進位值,最終轉換合適的位元組。而uNNNN表示Unicode編碼值,最終會轉換為UTF8的序列。

十六進位常量(Hexadecimal literals)

十六進位常量,以關鍵字hex打頭,後面緊跟用單或雙引號包裹的字元串,內容是十六進位字元串,如hex"001122ff"。

它的值會用二進位來表示。

十六進位常量和字元串常量類似,也可以轉換為位元組數組。

枚舉(Enums)

在Solidity中,枚舉可以用來自定義類型。它可以顯示的轉換與整數進行轉換,但不能進行隱式轉換。顯示的轉換會在運行時檢查數值範圍,如果不匹配,將會引起異常。枚舉類型應至少有一名成員。下面是一個枚舉的例子:

```

pragma solidity ^0.4.0;

contract test {

enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill }

ActionChoices choice;

ActionChoices constant defaultChoice = ActionChoices.GoStraight;

function setGoStraight() {

choice = ActionChoices.GoStraight;

}

// Since enum types are not part of the ABI, the signature of "getChoice"

// will automatically be changed to "getChoice() returns (uint8)"

// for all matters external to Solidity. The integer type used is just

// large enough to hold all enum values, i.e. if you have more values,

// `uint16` will be used and so on.

function getChoice() returns (ActionChoices) {

return choice;

}

function getDefaultChoice() returns (uint) {

return uint(defaultChoice);

}

}

```

代碼實例

通過合約代碼實例說明類型的使用,請前往區塊鏈技術小專欄查看[全文鏈接](xiaozhuanlan.com/topic/)。

參考文檔

[Solidity官方文檔-類型](solidity.readthedocs.io)

[深入淺出區塊鏈](learnblockchain.cn/) - 系統學習區塊鏈,打造最好的區塊鏈技術博客


推薦閱讀:

比特幣買片兒指南
LinkEye:它會是區塊鏈時代的信用基石嗎?
GCS遊戲公鏈:驅動區塊鏈遊戲走向主流的基礎設施
imToken 2.0 將會支持比特幣

TAG:以太坊 | 智能合约 |