Go開始:Go基本元素介紹

2023-09-04 15:00:43

本文深入探討了Go程式語言中的核心概念,包括識別符號、關鍵字、具名函數、具名值、定義型別、型別別名、包和模組管理,以及程式碼塊和斷行。這些元素是構成Go程式的基礎,也是編寫高質量程式碼的關鍵。

關注TechLeadCloud,分享網際網路架構、雲服務技術的全維度知識。作者擁有10+年網際網路服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智慧實驗室成員,阿里雲認證的資深架構師,專案管理專業人士,上億營收AI產品研發負責人。

在Go程式設計中,程式碼元素是構建軟體的基礎。本文旨在深入探討Go語言中的各種程式碼元素,包括函數、變數、型別和更多。我們還會涉及如何通過包(package)來組織這些元素,以及Go的關鍵字和識別符號規則。

識別符號與關鍵字


在任何程式語言中,識別符號和關鍵字都是核心概念,Go也不例外。識別符號用於命名各種型別的程式碼元素,如變數、常數、函數等。關鍵字是預留的詞彙,用於指示程式語言的特定操作。在本部分中,我們將詳細介紹Go語言中的識別符號和關鍵字。

Go中的識別符號

識別符號是用於標識各種程式實體(例如變數、函數、型別等)的名稱。在Go中,識別符號遵循以下規則:

  1. 必須以字母或下劃線(_)開頭。
  2. 可以包含字母、數位和下劃線(_)。
  3. 區分大小寫。

例如,以下都是有效的Go識別符號:

name
_x9
go_variable
Count123

以下是無效的識別符號:

9name // 以數位開頭
!var // 包含非法字元

Go關鍵字

Go語言有25個預留的關鍵字,不能用作識別符號。以下是這些關鍵字的列表以及它們的簡要解釋:

break       用於中斷迴圈或switch語句
default     用於switch語句,表示預設情況
func        定義新的函數
interface   定義介面
select      用於處理多個通道
case        用於switch和select語句中的條件分支
defer       用於確保函數呼叫在程式執行結束後發生
go          用於並行執行
map         定義map型別
struct      定義結構體
chan        定義通道型別
else        用於if-else結構
goto        用於無條件跳轉
package     定義包
switch      用於多路分支
const       定義常數或常陣列
fallthrough 用於switch語句,使得控制流穿透到下一個case
if          條件語句
range       用於迴圈遍歷陣列、切片、字串、map或通道
type        定義新的資料型別或型別別名
continue    跳過當前回圈的剩餘部分,開始下一次迭代
for         迴圈語句
import      匯入包
return      從函數返回
var         宣告變數

關鍵字範例

// 使用if-else關鍵字
if x > 10 {
    fmt.Println("x is greater than 10")
} else {
    fmt.Println("x is not greater than 10")
}

// 使用for關鍵字
for i := 0; i < 5; i++ {
    fmt.Println(i)
}

// 使用func和return關鍵字
func add(a int, b int) int {
    return a + b
}

具名的函數


在Go語言中,函數是一組執行特定任務的程式碼塊,具名函數即是有名稱的函數。本文將詳細討論Go中各類具名函數,包括常規函數、方法、高階函數、匿名函數和閉包。

常規函數

這是最基礎的函數型別。常規函數具有名稱,可以接受引數,並且可以返回值。

程式碼範例

// 常規函數,接受兩個int型別引數,返回int型別值
func add(a int, b int) int {
    return a + b
}

方法

在Go中,方法是一種特殊型別的函數,它作用於特定型別的變數,這個特定型別稱為接收者。

程式碼範例

type Circle struct {
    Radius float64
}

// Circle型別的方法,計算圓的面積
func (c Circle) Area() float64 {
    return 3.14159 * c.Radius * c.Radius
}

高階函數

高階函數是接受函數作為引數或返回一個函數的函數。

程式碼範例

// 高階函數,接受一個函數作為引數
func applyFunc(f func(int) int, value int) int {
    return f(value)
}

匿名函數與Lambda表示式

匿名函數是沒有名字的函數,通常用於臨時操作。

程式碼範例

// 匿名函數
add := func(a, b int) int {
    return a + b
}

閉包

閉包是一個函數值,它參照了其函數體之外的變數。簡單來說,這個函數「記住了」這些參照的變數。

程式碼範例

// 閉包範例
func outer() func() int {
    x := 0
    return func() int {
        x++
        return x
    }
}

具名的值


在Go語言中,具名的值主要包括變數和常數。這些都是用於儲存資料或代表特定值的識別符號。接下來,我們會分別探討變數和常數的各種型別和用法。

變數

變數是用於儲存資料的容器。在Go中,變數的宣告有多種方式,並且支援多種資料型別。

基本資料型別

Go支援一系列基本的資料型別,包括整數、浮點數、布林值、字串等。

var i int = 10          // 整數
var f float64 = 10.5    // 浮點數
var b bool = true       // 布林值
var s string = "hello"  // 字串

複合資料型別

Go還提供了陣列、切片、對映(Map)、結構體(Struct)等複合資料型別。

var arr [3]int = [3]int{1, 2, 3}           // 陣列
var slice []int = []int{1, 2, 3}           // 切片
var m map[string]int = map[string]int{"a": 1, "b": 2} // 對映
type Person struct {Name string; Age int}   // 結構體

指標型別

Go語言也支援指標,但不支援指標運算。

var p *int
i := 42
p = &i

常數

與變數不同,常數是不可變的值,一旦宣告,就不能更改。

基本常數型別

const pi float64 = 3.14159  // 浮點數常數
const str string = "Hello"  // 字串常數
const b bool = true         // 布林常數

列舉常數

在Go中,可以使用iota關鍵字生成一組增量的整數常數,通常用於列舉。

type Weekday int
const (
    Sunday Weekday = iota
    Monday
    Tuesday
)

常數表示式

Go支援常數表示式,允許用於計算的常數值在編譯期間進行運算。

const x = 2 + 3

定義型別和型別別名

Go語言不僅提供了一系列內建型別,還允許通過type關鍵字定義新的型別或為現有的型別建立別名。這兩者在語法上可能相似,但在型別系統中有不同的意義和用途。本篇文章旨在詳細介紹定義型別和型別別名的各種情況。

型別定義(Type Definition)

通過型別定義,你可以建立一個全新的型別,儘管它可能與某個現有型別在結構上完全相同。

基礎型別

下面是如何定義一個基於int的新型別MyInt

type MyInt int

複合型別

也可以基於複合型別來定義新型別:

type MyMap map[string]int
type Person struct {
    Name string
    Age  int
}

介面型別

你還可以定義介面型別,它包含了一組方法簽名:

type Writer interface {
    Write([]byte) (int, error)
}

型別別名(Type Alias)

型別別名並不建立新型別,只是為現有型別建立一個新名字。

type Integer = int

型別定義與型別別名的區別

型別定義和型別別名在Go中有著本質的區別。

  • 型別定義會建立一個全新的型別,它與其基礎型別在型別系統中是完全不同的。
  • 型別別名只是建立了一個新名稱,但並沒有建立新型別。

程式碼範例

type MyInt int
type YourInt = int

var a int
var b MyInt
var c YourInt

a = 1
b = MyInt(a)  // 需要顯式轉換
c = a        // 不需要轉換,因為YourInt只是int的別名

包和模組管理


Go語言通過包(Packages)和模組(Modules)來組織和管理程式碼。這兩者雖然在目的上有些許相似,但在用法和規模上各有特點。在本篇文章中,我們將深入探討Go中的包和模組管理,以及如何高效地使用它們。

包(Packages)

包是Go語言程式碼組織的基本單位。每個Go程式都是由包組成的,包用於封裝程式碼以實現可重用和可維護。

標準庫包

Go語言提供了豐富的標準庫,例如 fmt, net/http, io 等。

import "fmt"

func main() {
    fmt.Println("Hello, world!")
}

自定義包

你也可以建立自定義的包。通常情況下,每個資料夾就是一個單獨的包。

例如,建立一個名為 mathutils 的包:

// mathutils/add.go
package mathutils

func Add(a, b int) int {
    return a + b
}

使用自定義包:

import "mathutils"

func main() {
    sum := mathutils.Add(1, 2)
}

包的可見性

在Go中,以大寫字母開頭的函數或變數在包外是可見的(Public),以小寫字母開頭的則不是(Private)。

模組(Modules)

模組是包的集合。Go 1.11版本引入了模組的概念,旨在解決依賴管理問題。

初始化模組

使用 go mod init 初始化一個新模組。

go mod init mymodule

這將生成一個 go.mod 檔案,其中列出了模組名和依賴。

新增依賴

當你匯入一個新的包並執行 go buildgo get,依賴將自動新增到 go.mod 檔案。

升級和降級依賴

你可以使用 go get 命令升級或降級模組依賴。

go get -u example.com/some/[email protected]

程式碼塊與斷行

在Go程式設計中,理解如何有效地使用程式碼塊和斷行是編寫可讀、可維護程式碼的基礎。在本篇文章中,我們將深入瞭解Go語言中各種型別的程式碼塊和斷行規則。

程式碼塊(Code Blocks)

程式碼塊是由一對大括號{}包圍的程式碼序列。這些程式碼塊在不同的語境中有不同的作用。

函數體

最常見的程式碼塊是函數體,它包含函數的實現。

func sayHello() {
    fmt.Println("Hello!")
}

控制結構

ifforswitch 等控制結構也使用程式碼塊。

if true {
    fmt.Println("This is true.")
}

for i := 0; i < 3; i++ {
    fmt.Println(i)
}

宣告塊

常數和變數也可以在塊內宣告。

const (
    Pi = 3.14
    E  = 2.71
)

斷行(Line Breaks)

Go語言相對寬鬆的斷行規則讓你可以在多數表示式和宣告中自由地新增空白和換行。

語句結束

在Go中,大多數語句通過換行符或者分號來結束。

fmt.Println("This is the end of the statement")

長語句的斷行

對於較長的語句,Go允許在操作符附近斷行。

result := someVeryLongVariable +
    anotherVeryLongVariable -
    yetAnotherVeryLongVariable

函數呼叫和定義

在函數呼叫或定義時,引數也可以進行斷行。

func longFunction(
    param1 int,
    param2 string,
    param3 float64,
) {
    // 函數體
}

總結

通過深入探討Go語言的識別符號、關鍵字、具名函數、具名值、定義型別、型別別名、包和模組管理,以及程式碼塊和斷行,本系列文章旨在提供一個全面且深入的視角來理解Go程式設計的各個方面。這些元素共同構成了Go語言的基礎架構,熟練掌握它們是編寫可維護、高效和可延伸程式碼的關鍵。希望這些內容能夠幫助你在Go程式設計道路上更進一步,敬請期待我們接下來更多的深入文章和教學。

關注TechLeadCloud,分享網際網路架構、雲服務技術的全維度知識。作者擁有10+年網際網路服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智慧實驗室成員,阿里雲認證的資深架構師,專案管理專業人士,上億營收AI產品研發負責人。
如有幫助,請多關注
個人微信公眾號:【TechLeadCloud】分享AI與雲服務研發的全維度知識,談談我作為TechLead對技術的獨特洞察。
TeahLead KrisChang,10+年的網際網路和人工智慧從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿里雲認證雲服務資深架構師,上億營收AI產品業務負責人。