Go 程式設計教學:變數和資料型別

在上一篇文章中,我們談到如何建立 Go 專案,並且開始撰寫第一個程式,相信讀者都已經實際操作過了。接著,我們就要開始談程式設計最基本的部分:變數 (variable) 和資料型別 (data type)。電腦程式很大一部分是在操作各種資料 (data),本文會以程式設計的角度來討論這個議題。

變數

在撰寫程式時,我們會將資料存在變數中,在後續的程式中可呼叫該變數。可以將變數想成一個帶有標籤的盒子,變數名稱是標籤,而變數內部存的是值 (value),也就是資料。

我們以一個簡單的例子來展示變數的使用:

宣告變數使用 var 關鍵字,在這個例字中,我們宣告變數 name,並宣告其資料型別為 string (字串),我們會在後文中詳述資料型別,簡單地說,就是資料的類型。接著,我們指派 (assign) 字串 “Michael” 給變數 name,指派使用等號 (=)。最後,我們在程式中呼叫變數 name

由於宣告變數及指派值是常見且基本的動作,Go 提供另一個語法,如下例:

在這個例子中,我們省略變數的型別,Go 會用變數的值自動判定變數的型別。為什麼 Go 要刻意使用這種語法而不直接採用等號?這可能是要在視覺上有所區別,便於日後觀看程式碼時了解程式的意圖,有些程式設計者覺得這個語法有些冗餘。

如果我們沒有指派變數的值,Go 會根據不同的資料型別自動指派相對應的初始值;然而,這個初始值通常不會是我們所要的值。一般來說,大部分 Gopher 會用第二種方法宣告變數,只有在需要時才用第一種方法宣告變數。

Go 宣告變數有以下四種方式:

  • var:宣告變數 (variable)
  • const:宣告常數 (constant)
  • func:宣告函式 (function)
  • type:宣告新型別

我們已經看過 var 了,而 const 用來宣告常數,常數宣告後即不可變動。以下是範例:

習慣上,常數會使用全大寫,像是 CONSTANT_NAME。這個範例僅是用來展示如何宣告常數,實際上,math 套件有一個更精準的圓周率常數 math.Pi,我們不該另外宣告一個。

關鍵字 func 是用來宣告函式,就像我們宣告主函式一般;type 則是用來宣告新型別。我們將於後續文章中介紹。

資料型別

Go 變數會帶有相對應的型別,型別可以規範變數在程式中相對應的動作,例如,數字可以加減乘除,布林值可進行邏輯運算等。Go 有以下四大類型別:

  • 基本型別 (basic types)
  • 聚合型別 (aggregate types)
  • 參考型別 (reference Types)
  • 介面型別 (interface types)

基本型別包括以下數種型別:

  • 數字
    • 整數 (integers)
      • 有號:int8, int16, int32, int64, int
      • 無號:uint8, uint16, uint32, uint64, uint
      • rune,內部為 int32,表 unicode code point
      • byte,內部為 uint8,表一段 raw data
      • uintper,儲存記憶體位置
    • 浮點數 (floating-point numbers)
      • 單精度 (6 位精確度):float32
      • 倍精度 (15 位精確度):float64
    • 複數 (complex numbers)
      • 單精度:complex64,由 32 位元的實數和虛數組成
      • 倍精度:complex128,由 64 位元的實數和虛數組成
  • 字串 (string)
  • 布林值 (boolean)

雖然數字型別有很多種,這是為了和電腦內部相對應,對於一般使用者來說,不需要去細別數字的型別,整數用 int,浮點數用 float64 即可。如果需要用 Go 進行大數 (big number) 運算,則需使用 math/big 套件,因為電腦內部無法直接表示大數,需要用軟體去模擬。

要注意的是,Go 程式在數字過大過小時會溢位 (overflow) 或下溢 (underflow),這是由於電腦內部表示數字的方式所帶來的限制。實例如下:

在大部分的情形下,溢位不是我們期待的結果,但 Go 目前沒有特別的方法防止溢位,如果預期數字會比較大,可能要用較大位數的型別或是轉用大數運算套件。

在 Go 程式中,不能直接將不同型別的數字相加,會引發錯誤。見以下實例:

解套的方式是將其中一個變數轉型,Go 提供 int()float32()float64() 等內建函式可進行轉型的動作。

Go 提供以下聚合型別:

  • 陣列 (array)
  • 結構 (struct)

透過聚合型別,單一變數可容納多個值。我們將會後續文章中介紹,目前暫不說明。

Go 提供以下參考型別:

  • 指標 (pointer)
  • 切片 (slice)
  • 字典 (map)
  • 函式 (function)
  • 通道 (channels)

參考型別的內部使用指標 (pointer),同樣地,我們會於後續文章中另行介紹。

經過本文,讀者應該對變數和資料型別有一些概念。我們將在下一篇文章中介紹運算子 (operator),透過運算子,可以進一步操作資料,達成更多的功能。