位元詩人 [Golang] 程式設計教學:使用變數 (Variable)

Golang變數
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

變數 (variable) 是電腦程式中用來操作資料 (data) 的一種語法特性。本文介紹如何在 Go 語言中使用變數。

實字 (Literal)

在介紹變數前,我們先介紹實字 (literal)。實字是在電腦程式中直接寫死的資料,在初階的電腦程式中常見。教學用的程式用實字是為了方便,實務上,我們會從電腦程式外部讀入資料,真正用到實字的時候反而少。

像是以下的 Hello World 程式就用到實字:

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

在這個程式中,"Hello World" 的部分就是字串形態的實字。

宣告和使用變數 (Variable)

在以下範例中,我們建立和使用變數 msg:

package main

import "fmt"

func main() {
    // Declare the variable `msg`.
    var msg string
    // Assign some value to `msg`.
    msg = "Hello World"

    // Use `msg` as a function parameter.
    fmt.Println(msg)
}

在第一行程式中,我們使用 var 保留字宣告變數 msg,該變數的型別為 string (字串)。

在第二行程式中,我們將 "Hello World" 字串指派到 msg。

最後,我們把 msg 做為函式的參數,傳入 fmt 套件的 Println 函式中。Println 會把傳入的字串印在終端機上。

雖然這個例子很短,我們可以從這個例子中看出變數有三個要件:

  • 識別字 (identifier)
  • 該變數的資料型別 (data type)
  • 該變數的值 (value)

透過宣告變數,我們賦予電腦程式新的識別字。原本 Go 語法中沒有此識別字,是程式設計師透過宣告變數新增的。

在電腦程式中,變數具有資料型別 (data type)。資料型別是資料的元資訊 (metadata),用來規範資料合法的操作。我們於先前的文章介紹過資料型別。讀者可回到先前的文章複習一下。

變數所指向的資料稱為值,所以值就是資料。

由於宣告變數是一個常見的動作,Go 語言提供另一種宣告變數的形式:

package main

import "fmt"

func main() {
    // Declare the variable `msg` and assign it some value.
    msg := "Hello World"

    // Use `msg` as a function parameter.
    fmt.Println(msg)
}

請注意在這種形式中,我們使用 := 來指派值,和先前的形式相異。在這種形式中,我們不需要加上型別的標註。因為 Go 語言會自動從值中推斷變數的型別。

宣告和使用常數 (Constant)

在以下例子中,我們宣告常數 PI:

package main

import "fmt"

func main() {
    // Declare the constant `PI`
    const PI float64 = 3.1415927

    // The radius of a circle.
    r := 10.0

    // Get the area of the circle.
    fmt.Println(PI * r * r)
}

在這個範例中,我們使用 PI 計算一個圓的面積。其實 Go 語言內建一個更精準的圖周率,這個例子只是展示常數的使用方式。

宣告常數和宣告變數的概念雷同,只是把 var 換成 const 即可。但常數要直接用實字填值,不能由外部取得值。

宣告常數的好處在於常數宣告後即不能修改。若我們試圖修改常數,會在程式編譯時引發錯誤,提醒我們必需改掉錯誤的動作。

識別字 (Identifier) 的規範

不論是宣告變數或宣告常數,這些動作都是在 Go 程式中新增識別字。識別字要符合以下規範:

  • 首字是字母 (letters) 或底線 (underscore)
  • 餘字可為字母、數字、底線
  • 不可使用保留字 (keywords) 或內建識別字 (predeclared identifiers)

使用單一底線做為識別字時,代表捨棄接收到的值。這項特性通常會搭配函式呼叫使用。參考以下例子:

package main

import (
    "fmt"
    "log"
)

func main() {
    _, err := fmt.Println("Hello World")

    if err != nil {
        log.Fatal(err)
    }
}

這個例子有點超出目前介紹的內容,但這個例子很短,仍然可以試著閱讀一下。

我們先前講過,fmt 套件的 Println 會回傳兩個值。在一般情形下,我們不會用到這兩個回傳值。在此處,我們捨棄第一個回傳值,但檢查第二個回傳值 err 是否為空。當 err 不為空時,即強制結束程式並印出錯誤訊息。

保留字 (Keywords)

保留字在程式碼中有特定的含義,故不能做為識別字。像是先前看到的 package、import、func、var、const 等都是保留字。Go 語言目前有 25 個保留字:

break        default      func         interface    select
case         defer        go           map          struct
chan         else         goto         package      switch
const        fallthrough  if           range        type
continue     for          import       return       var

在主流程式語言中,Go 語言的保留字算少。ANSI C 的保留字有 32 個;Python 3 的保留字有 45 個;C++ 的保留字則超過 100 個。保留字的數量越多,往往表示該語言的概念越複雜。

學程式設計時,請不要背誦保留字。在寫程式的過程中,自然而然會把保留字記起來。編輯器也會用顏色來提示保留字出現的地方。

內建識別字 (Predeclared Identifier)

Golang 官網的頁面有一份內建識別字的清單:

Types:
    bool byte complex64 complex128 error float32 float64
    int int8 int16 int32 int64 rune string
    uint uint8 uint16 uint32 uint64 uintptr

Constants:
    true false iota

Zero value:
    nil

Functions:
    append cap close complex copy delete imag len
    make new panic print println real recover

這些識別字已定義了,故不能當成識別字。

識別字的撰碼風格

在設置識別字時,通常會採用下列三種風格之一:

  • PascalCase
  • camelCase
  • snake_case

在 Go 語言中,使用 PascalCase 和 camelCase 有實質的意義,而非僅是風格的差異。當識別字使用 PascalCase 時,表示該識別字是公開的 (public)。反之,當使用 camelCase 時,表示該識別字是私有的 (private)。

因此,建議大部分的識別字都用 camelCase,而要公開的識別字用 PascalCase 來命名。至於 snake_case 通常不使用。

結語

在本文中,我們介紹了變數的組成要素及使用變數的方式。透過變數,就可以在電腦程式中操作資料。

關於作者

位元詩人 (ByteBard) 是資訊領域碩士,專注於從探索到產品的開發過程,並以工具驅動的方式改善專案。喜歡以開源專案作為成果,回饋社群。

主要方向包括:自用工具的打磨 (dogfooding)、編譯器技術在工具開發中的應用,以及將研究轉化為可維護的開源成果。

除了技術之外,也喜歡日本料理和黑咖啡,偶爾自助旅行,將生活中的靈感融入技術隨筆。