了解基本資料類型

已完成

Go 是強類型語言。 您所宣告的每個變數都會繫結至特定的資料類型,而且只會接受符合這種類型的值。

在 Go 中,您有四種類別的資料類型:

  • 基本類型:數字、字串和布林值
  • 彙總類型:陣列和結構
  • 參考類型:指標、配量、地圖、函式和通道
  • 介面類型:介面

在本課程模組中,我們只會說明基本類型。 如果您不知道其他類型是什麼,請不要擔心。 我們會在即將推出的課程模組中加以討論。

讓我們從探索數值資料類型開始吧。

整數數字

在一般情況下,用來定義整數類型的關鍵字為 int。 但是 Go 另外提供了 int8int16int32int64 類型,這些是大小分別為 8、16、32 或 64 位元的 int。 當您使用 32 位元的作業系統時,如果只使用 int,則大小通常為 32 位元。 在 64 位元系統上,int 大小通常是 64 位元。 但這種行為會視不同的電腦而異。 您可以使用 uint。 但是,只有在基於某些原因而必須將值表示為不帶正負號的數字時,才能使用此類型。 Go 也提供了 uint8uint16uint32uint64 類型。

以下是如何在 Go 中使用各種整數類型的範例:

var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)

在大部分的情況下,您會使用 int,但您必須知道其他整數類型,因為在 Go 中,即使整數的原始大小為 32 位元,但 intint32 仍然不同。 換句話說,您必須在需要轉換時明確地進行轉換。 如果您嘗試在不同類型之間執行數學運算,您將會收到錯誤訊息。 例如,假設您有此程式碼項目:

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)

當您執行程式時,您會收到此錯誤:

invalid operation: integer16 + integer32 (mismatched types int16 and int32)

如您所見,在 Go 中將某個型別的值轉換成另一個型別時,必須明確陳述新的型別。 我們將在此課程模組的最後,討論如何正確轉換類型。

在學習 Go 的過程中,您可能會接收到有關 rune 的資訊。 rune 只是 int32 資料類型的別名。 其用來代表 Unicode 字元 (或 Unicode 程式碼項目)。 例如,假設您有下列程式碼:

rune := 'G'
fmt.Println(rune)

當您執行上述程式碼片段時,您可能預期會在命令提示字元中看到程式輸出 G。 但是您看到數字 71,則代表 G 的 Unicode 字元。 我們將在即將推出的課程模組中詳細討論 rune。

您可以參閱 Go 原始程式碼,以了解每個類型的範圍。 了解每個類型的範圍可協助您選擇適當的資料類型,而且也可避免浪費記憶體中的位元數。

挑戰 1

設定 int 類型的另一個變數,並使用 integer32integer64 變數中的值來確認系統上變數的原始大小。 如果您使用的是 32 位元的系統,並且使用高於 2,147,483,647 的值,您將會收到如下所示的溢位錯誤:constant 9223372036854775807 overflows int

問題解決方案

package main

import "fmt"

func main() {
   var integer32 int = 2147483648
   fmt.Println(integer32)
}

挑戰 2

宣告不帶正負號的變數 (例如 uint),並以負數值 (例如 -10) 將其初始化。 當您嘗試執行程式時,您應該會收到如下所示的錯誤:constant -10 overflows uint

問題解決方案

package main

import "fmt"

func main() {
   var integer uint = -10
   fmt.Println(integer)
}

浮點數

Go 提供兩種浮點數大小的資料類型:float32float64。 當您需要儲存較大的數字,而且這些數字不符合任何先前提及的整數類型時,就可以使用這些類型。 這兩個類型之間的差異是可保存的位元大小上限。 請查看下列幾行,以了解如何使用這兩個類型:

var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)

您可以使用 math 套件中提供的 math.MaxFloat32math.MaxFloat64 常數,來找到這兩個類型的限制。 使用下列程式碼,可在命令提示字元中輸出浮點值上限:

package main

import (
    "fmt"
    "math"
)    

func main() {
    fmt.Println(math.MaxFloat32, math.MaxFloat64)
}

當您需要使用十進位數時,浮點數類型也很實用。 例如,您可以撰寫類似下列程式碼的內容:

const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34

請注意,在先前的程式碼中,Go 會透過使用的值來推斷資料類型。

布林值

布林值類型只有兩個可能的值:truefalse。 您可以使用 bool 關鍵字來宣告布林值類型。 Go 與其他程式設計語言不同。 在 Go 中,您無法將布林值類型隱含地轉換為 0 或 1。 您必須明確地執行轉換。

因此,您可以使用下列方式宣告布林值變數:

var featureFlag bool = true

在我們在即將推出的課程模組中,我們會在談論到 Go 中的控制流程陳述式時,使用布林值資料類型。 我們也將在稍後的課程模組中使用這些類型。

字串

最後,我們來看看任何程式設計語言中最常見的資料類型:字串。 在 Go 中,我們使用 string 關鍵字來表示字串資料類型。 若要初始化字串變數,您必須在雙引號 (") 中定義其值。 單引號 (') 會用於單一字元 (也會用於 rune,如上一節所述)。

例如,下列程式碼會示範兩種宣告和初始化字串變數的方式:

var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)

有時候您可能會需要逸出字元。 若要這樣做,請在字元前面使用反斜線 (\)。 例如,以下是使用逸出字元的最常見範例:

  • \n 代表新的一行
  • \r 代表歸位字元
  • \t 代表 Tab
  • \' 代表單引號
  • \" 代表雙引號
  • \\ 代表反斜線

使用下列程式碼片段來測試逸出字元:

fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)

您應該會看到下列輸出 (包括新行):

John Doe        (alias "Foo")

預設值

到目前為止,幾乎每次宣告變數時,我們都已使用值來將其初始化。 但在 Go 中,與其他程式設計語言不同的是,在您未初始化變數時,所有資料類型都已有預設值。 此功能很方便,因為您不需要在使用變數之前,先檢查變數是否已初始化。

以下是我們目前為止探索到的一些類型預設值清單:

  • 0int 類型 (及其所有子類型,例如 int64) 的預設值
  • +0.000000e+000float32float64 類型的預設值
  • falsebool 類型的預設值
  • string 類型的預設值為空值

執行下列程式碼片段,以確認先前列出的預設值:

var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)

您可以使用與此程式碼類似的程式碼,來判斷此處未探索到的資料類型預設值。

類型轉換

在上一節中,我們已確認隱含轉換不適用於 Go。 在 Go 中,必須明確地執行轉換。 Go 提供了一些原生方法,可將一個資料類型轉換成不同資料類型。 例如,其中一個方法就是針對每個類型使用內建函式,如下所示:

var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)

在 Go 中進行轉換的另一種方法是使用 strconv 套件。 例如,若要將 string 轉換成 int (反之亦然),您可以使用下列程式碼:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, _ := strconv.Atoi("-42")
    s := strconv.Itoa(-42)
    fmt.Println(i, s)
}

執行上述程式碼,並確認其已執行並輸出 -42 兩次。

請注意,在上述程式碼中,有一個用來作為變數名稱的底線 (_)。 在 Go 中,_ 表示我們不會使用該變數的值,而是要忽略該值。 否則,程式將不會進行編譯,因為我們需要使用所有宣告的變數。 接著我們會回到本主旨,且您會在即將推出的課程模組中了解 _ 通常代表什麼。