Go:關鍵字與預定義標識符

語法是一門編程語言的基礎,而關鍵字又是語法的基礎,我們通過這些關鍵字構建出一個個應用程序。不知道大家是不是和我一樣,對於這些語法,通常採用 “熟能生巧” 的辦法掌握,很少系統的記憶。直到有一次,編寫 switch 語句時,在沒有添加 break 的情況下,case 匹配成功後卻未繼續往下執行,這是爲什麼?原來 ,Go 語言的 switch case 自帶 break,如果希望繼續往下執行,則需要用到fallthrough 關鍵字。原來如此,這個錯誤似乎有些低級,只怪自己沒有熟練的掌握關鍵字。那有沒有辦法,即便一個新手,沒有那麼多 coding 經驗,也不會在這種問題上犯錯誤?我的建議是,從掌握關鍵字開始,當然也離不開 36  個預定義標識符,咱們一起來看看吧。

爲了方便記憶,我將關鍵字與預定義標識符重新整理並按功能或創建方式進行了分組。

關鍵字

關鍵字是由一組具有特殊含義的單詞組成,開發者在聲明變量名、函數名等標識符時是禁止使用的。通過關鍵字,可以大致看出一門編程語言的特點,關鍵字是很適合作爲了解編程語言的入門方式。

與其他編程語言相比,Go 語言的關鍵字非常之少,只有 26 個。這些關鍵字的功能包括聲明變量名、常量名、方法名、創建新類型、條件語句、循環語句等,Go 語言的 36 個預定義標識符也是由它們定義的。

聲明關鍵字

先來了解一下聲明關鍵字,代碼程序本質上是對一堆數據進行操作,這些數據通過變量名、或常量名等標識符保存在內存中,之後我們操作標識符即可。但源碼中可能存在多種關鍵字或標識符,編譯器難以僅僅根據標識符辨別變量、常量。所以需要通過聲明關鍵字進行,其中,var 聲明變量名、const 聲明常量名、type 聲明新類型或類型別名、func 聲明一個方法或函數、package 則用來聲明包名。

這個關鍵字相信大家都不陌生,它是類型變量聲明方式之一,另外 Go 語言還提供短聲明方式,但它不在關鍵字範圍內,所以這裏不做介紹。與其它聲明方式不同,需要格外注意的是:用 var 聲明的變量是未初始化、不佔用內存空間的。系統會默認將變量值設置成類型的零值,如數值變量的默認值爲 0 ,字符串變量的默認值爲空,如果是接口或通道,則默認 nil 。通過 var 可以一次聲明一個或多個變量。

我們通常使用 var 聲明一般類型變量,或在函數體外部聲明全局變量。由於變量未初始化,如果創建的是切片、映射或通道變量,是無法直接使用的,因此在創建上述幾類變量時,建議使用內置函數 make()

// 聲明一個 int 類型的變量
var a int
// 聲明多個 int 類型的變量
var b, c, d int
// 聲明一組不同類型變量
var (
 e int
 f string
)
// ...

常量值只能是數字、字符、字符串或布爾值,聲明以後不能再修改。設置超過一個的常量時,可以像 var 聲明變量那樣,使用括號將常量組合在一起。

Go 語言中沒有枚舉類型 (enum),不過可以通過 const 聲明一組常量,再使用預定義標識符 iota 生成枚舉值來實現。

// 聲明一個常量
const a = 1   // 1
// 聲明多個常量和實現一個簡單的枚舉
const (
 b = 2    // 2
 c = 3    // 3
 d = iota // 2
 e        // 3
 f        // 4
)

Go 語言的類型非常靈活,我們可以根據需求,通過 type 關鍵字創建類型,或定義類型別名。預定義標識符中的基本類型便是由 type 創建,在開發過程中多用於創建結構體或接口類型。

// 創建新類型 bool
type bool bool
// 創建類型別名 byte
type byte = uint8
// 創建結構體 Scanner
type Scanner struct {
 // ...
}
// 創建接口 error,並定義 Error 方法
type error interface {
 Error() string
}

Go 語言的方法與函數很相似,在 func 和方法名之間加了一個參數的就是方法,用於定義類型的行爲,沒有加參數的叫函數。方法跟函數都可以有任意多參數跟返回值。

// 聲明一個結構體類型
type Scanner struct {
 // ...
}
// 聲明一個方法:用於定義結構體 Scanner 的行爲
func (s *Scanner) next() {
 // ...
}
// 聲明一個函數
func next() {
 // ...
}
// 聲明一個匿名函數
func {

}
// main 包
package main

創建類型關鍵字

Go 語言除了數值、布爾、字符串等基本類型,還有一些派生類型,根據開發需求通過關鍵字定義:保存鍵值對的映射(map)類型、可以包含任何類型的結構體(struct)、爲類型定義方法的接口(interface)類型、併發需要用到的 Goroutine 和通道(chan)類型等。

一般使用 make() 函數創建,大部分基本類型都可以當做映射類型的鍵,但所有鍵的類型必須相同。當使用 delete() 刪除不存在的鍵時,程序不會報錯,而是返回對應類型的零值。由於映射屬於引用類型,不管保存了多少數據,傳遞上都很廉價。

// 創建一個空的映射並填充數據
a := make(map[int]string)
a[1] = "a"
a[2] = "b"

使用聲明關鍵字 type 與結構類型 struct 創建一個結構體類型,它主要用於聚合和嵌套,結構體內可以包含任何類型的值,甚至一個結構體。不過需要注意的是,當結構體內嵌套了一個結構體,並且它們擁有相同的變量名時,最外層會被優先調用。

type Scanner struct {
 // immutable state
 file *token.File  // source file handle
 dir  string       // directory portion of file.Name()
 src  []byte       // source
 err  ErrorHandler // error reporting; or nil
 mode Mode         // scanning mode
 // ...
}

使用聲明關鍵字 type 與接口類型 interface 創建一個接口。在接口裏,我們爲類型聲明一個或多個方法簽名。代碼中經常看到的 interface{} 表示空接口,它接受任意類型值,但是當我們使用該值時,需要進行類型斷言,switch 的類型開關便是用於接口類型。

type Reader interface {
 Read([]byte) (n int, err error)
}
type ReadWriter interface {
 Reader
 Writer
}

使用 make() 函數創建,爲併發提供一種無鎖通信方式,用於解決多個併發之間的通信問題。在創建通道時,可設置緩衝區,設置了緩衝區的通道又叫非阻塞通道,未設置緩衝區通道叫阻塞通道。

// 創建帶緩衝區通道
a := make(chan string,5)
// 創建不帶緩衝區通道
b := make(chan string)

創建 goroutine 處理併發,讓程序執行代碼的同時並行去做另外一些事情,多個 goroutine 之間使用通道傳輸數據。

// 創建 goroutine
go func(){
 //..
}

創建條件語句關鍵字

if i == 0 {
 // ... 
}
if i := len(s); i >= 0 {
 // ...
}
if !ok {
 // ...
}

創建循環語句關鍵字

// 無限循環
for {
      // ...
}
// while循環
for booleanExpreesion {
     // ...
}
// 一般使用
for i=0;i<=100;i++{
     // ...
}

流程控制語句關鍵字等

預定義標識符

Go 語言的預定義標識符由類型、值、函數三部分組成,它們也叫內置類型、內置值、內置函數,通過vartypeconstfunc 這 4 個關鍵字定義。其中,內置類型分爲數值、字符串、布爾,我們前面說到的基本類型便是指這些。而內置的函數則主要針對非內置類型,如切片、映射、通道等特殊類型的操作,除此之外,還有異常處理函數。這裏僅介紹內置函數。

總結

這篇文章是對 Go 語言基礎的簡單介紹,更多的是對關鍵字和預定義標識符的歸納總結,幫助形成基本構架認知。在介紹有的關鍵字與預定義標識符時,雖是寥寥幾筆,但並不能因此認爲它不重要,或簡單好懂,它的原理以及操作運用可能遠比我們想象中要複雜,甚至還有一些意想不到的用途,後面的文章中我們會挑選一些來做深度解析。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/tr6JwRV93IJtSXdRB6xAOQ