天天看點

一起來學Go --- (go的枚舉以及資料類型)

枚舉

枚舉指一系列的相關的常量,比如下面關于一個星期的中每天的定義,通過上篇博文,我們可以用在const後跟一對圓括号的方式定義一組常量,這種定義法在go語言中通常用于定義枚舉值。go語言并不支援衆多其他語言明确支援的enum關鍵字。

下面是一個正常的枚舉表示法,其中定義了一系列整型常量。

const (
    Sunday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    numberOfDays       // 這個常量沒有導出       

)
      

  同go語言中的其他符号(symbol)一樣,以大寫字母開頭的常量在包外可見。

        以上列子中 numberOfDays為包内私有,其他符号則可被其他包通路。

資料基本類型

布爾類型: bool

整數類型: int8、byte、int6、int、uint、uintptr等。

浮點類型: float32、float64。

複數類型:complex64、complex128。

字元串:string。

字元類型:rune。

錯誤類型:error。

處上之外,go語言還支援一下的複合類型。

指針(pointer)

數組(array)

切片(slice)

字典(map)

通道(chan)

結構體(struct)

接口(interface)
      

  上述類型的特點在于使用友善,但使用者不能對這些類型的長度做任何假設。對于正常的開發來說,用int和uint就可以了,沒必要用int8之類明确指定長度的類型 ,以免導緻移植困難。

 布爾類型

go語言中的布爾類型與其他語言基本一緻,關鍵字也是 bool ,可指派為預定義的true和false。

var test bool
test = true
test_two := (1 == 2)          // test_two也會被推導為bool類型

PS: 布爾類型不能接受其他類型指派,不支援自動或強制的類型轉換。

下面一些錯誤的文法:
var  a bool
a = 1                        // 文法錯誤
a = bool(1)                  // 文法錯誤

以下的用法才是正确:
var one bool
one = (1 != 0)               // 正确文法
fmt.Println("result:", one)  // go的輸出   Println

輸出結果:
result : true
      

 整型:

整型是所有語言裡最基礎的類型了。

類型                            長度                                    值範圍
int8                            1                                 -128 ~ 127  
uint8(既byte)                   1                                   0 ~255
int16                           2                               -32 768 ~ 32 767
uint16                          2                                  0~65 535
int32                           4                          -2 147 483 648 ~ 2 147 483 647
uint32                          4                              0 ~ 4 294 967 295
int64                           8                 -9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
uint64                          8                           0 ~ 18 446 744 073 709 551 615
int                          因平台而定                                因平台而定  
uint                         因平台而定                                因平台而定
uintptr                        同指針            在32位平台下為4位元組,64位平台下為8位元組
      

  ①、類型表示

需要注意的是,int和int32在go語言裡被認為是兩種不同的類型,編譯器也不會幫你自動做轉換類型,比如以下的列子會有編譯錯誤:

var value2 int32
value1 := 64                        // value1将會被自動推導為int類型
value2 = value1                     // 編譯錯誤 

編譯錯誤類似于:
cannot use valu1 (type int) as type int32 in assignment。

使用強制類型轉換可以解決這個編譯錯誤:

value2 = int32 (value1)             //編譯通過
      

  當然,開發者在做強制類型轉換時,需要注意資料長度被截斷而發生的資料精度損失(比如将浮點數強制轉為整數)和值溢出(值超過轉換的目标類型的值範圍時)問題。

  ②、數值運算

go語言支援下面的正常整數運算: +、-、*、/、和%。加減乘除就不解釋了,需要說下的是,%和C語言中一樣是求餘運算,比如:

5 % 3                              // 結果: 2
      

  ③、比較運算

go語言支援以下的幾種比較運算符:   >  、 <  、 ==、>=、 <=和!=。這一點與其他大多數的語言相通,與C語言完全一緻。

  ④、運算符

運算                    含義                        樣   列
x << y                 左移                       124 << 2   // 結果為496
x >> y                 右移                       124 >> 2   // 結果為31
x ^ y                  異或                       124 ^ 2    // 結果為126
x & y                   與                        124 & 2   // 結果為0
x | y                   或                        124 | 2   // 結果為126
^x                     取反                        ^2       // 結果為3
      

  go語言的大多數位運算符與C語言都比較類似,除了取反在C語言中是~x,而在go語言中是^x。

浮點型

浮點型用于表示包含小數點的資料,比如1.234就是一個浮點型資料,在go語言中的浮點類型采用IEEE-754标準的表達方式。

①、浮點數表示

go語言定義了兩個類型float32和float64,其中float32等價于C語言的float類型,float64等價于C語言的double類型。

在go語言中,定義一個浮點數變量的代碼如下:

var fvalue1 float32

fvalue1 = 12
fvalue2 := 12.0     // 如果不加小數點,fvalue2會被推導為整型而不是浮點型
      

  對于以上列子類型被自動推導的fvalue2,需要注意的是其類型将被自動設為float64,而不管賦給它的數字是否使用32位長度表示的,是以,對于以上列子,下面的指派将導緻編譯錯誤:

fvalue1 = fvalue2

而必須使用這樣的強制類型轉換:

fvalue1 = float32(fvalue2)
      

 ②、浮點數比較

因為浮點數不是一種精确的表達方式,是以像整型那樣直接用==來判斷兩個浮點數是否相等是不可行的,這可能會導緻 不穩定的結果 。

下面是一種推薦的替代方案。import "mat// p為使用者自定義的比較精度, 比如:0.00001

func IsEqual(f1, f2, p float64) bool {
    return math.Fdim(f1, f2) < p
}  
      

  複數類型

複數實際上由兩個實數(在計算機中用浮點數表示)構成,一個表示 實部(real),一個表示虛部(imag),如果了解了數學上的複數是怎麼回事,那麼go語言的複數就非常容易了解了。

①、複數表示

複數示例:

var value1 complex64            // 由2個float32構成複數類型

value1 = 3.2 + 12i
value2 := 3.2 + 12i               //value2是complex128類型
value3 := complex(3.2, 12)    //value3結果同value2
      

  ②、實部與虛部

對于一個複數z = complex(x, y),就可以通過go語言内置函數real(z)獲得該複數的實部,也就是x,通過imag(z)獲得該複數的虛部,也就是y。

字元串

在go語言中,字元串也是一種基本類型,相比之下,C/C++語言中并不存在原生的字元串類型,通常使用字元數組來表示,并以字元指針來傳遞。

go語言中一下是字元串的聲明和初始化。

var str string   // 聲明一個字元串變量

str = "Hello world"    // 字元串指派

ch := str[0]              // 取字元串的第一個字元
fmt.Printf("The length of \"%s\" is %d \n", str, len(str))
fmt.Printf("The first character of \" %s\"is %c.\n", str, ch)

輸出結果:

The length of "Hello world" is 11

The first character of "Helllo world" is H.
      

  字元串的内容看可以用類似于數組下标的方式擷取,但與數組不同,字元串的内容不能再初始化後被修改,比如一下列子:

str := "Hello world"    //  字元串也支援聲明時進行初始化的做法

str[0] = "x"               //  編譯錯誤

編譯器會報類似如下錯誤:

cannot assign to str[0]
      

  字元串的操作 

運算                    含義                                        樣列

x + y                  字元串連接配接                   "Hello" + "123"    //  hello123
len(str)               字元串長度                           len("hello")   // 5
s[*]                    取字元                             "hello" [1]       // e

更多方法請參考string标準庫包!!!

   
      

  ①字元串周遊

go語言中支援兩種周遊方式,一種是以位元組數組的方式周遊:

str := "Hello,世界"
n := len(str)
for i := 0; i < n; i++ {
    ch := str[i]    // 依據下标取字元串中的字元,類型為byte
    fmt.Println(i, ch)
}

結果:
0 72
1 101
2 108
3 108
4 111
5 44
6 32
7 228
8 184
9 150
10 231
11 149
12 140
      

  可以看出,這個字元串長度為13,盡管從直覺上來說,這個字元串應該隻有9個字元,這是因為每個中文字元在UTF-8中占三個位元組,而不是壹個位元組。

另一種是以Unicode字元周遊:

str := "Hello, 世界"
for i, ch := range str {
    fmt.Println(i, ch)    // ch的類型為true
}

結果:
0 72
1 101
2 108
3 108
4 111
5 44
6 32
7 19990
10 30028
      

  以Unicode字元方式周遊時,每個字元的類型是rune(早期的go語言用int類型表示Unicode字元),而不是byte。

字元類型

在go語言中支援兩個字元類型,一個是byte(實際上是uint8的别名),代表UTF-8字元串的單個位元組的值,另一個是rune,代表單個Unicode字元。

繼續閱讀