Go 語言 15 個內置函數詳解
?01 介紹
Go 語言為了方便我們開發,提供了 15 個內置函數,比如 len、cap、make? 和 new 等。
本文我們結合 Go 內置函數官方文檔[1],介紹一下 Go 語言中的內置函數。
02 內置函數
內置函數?append:
內置函數 append 可以將元素追加到切片的末尾。
當我們使用 append 向切片中追加元素時,切片的底層數組必須具有足夠的容量,否則,將會分配一個新的底層數組。
輸出結果:
所以,我們需要注意的是,append 之后的切片賦值給同一個變量。
除了使用 append 向切片中追加元素之外,我們還可以向切片中追加另一個切片,例如:
此外,還可以使用 append 將字符串追加到字節切片中,例如:
內置函數?copy:
內置函數 copy 可以將源切片中的元素拷貝到目標切片。
輸出結果:
copy? 的返回值是拷貝元素的個數,返回值是 len(src)? 和 len(dst) 的最小值。
需要注意的是,源切片和目標切片中的元素可能會重疊。
此外,還可以使用 copy 將一個字符串中的字節拷貝到一個字節切片中,例如:
內置函數?delete:
內置函數 delete? 通過指定鍵 m[key]? 刪除 map 中的元素。
如果 map? 是 nil? 或沒有元素,delete 不做任何操作。
輸出結果:
內置函數 ?len:
內置函數 len 返回值的長度,值的類型不同,值的長度含義也不同。
- array 數組中元素的個數。
- *array? 數組指針中元素的個數,即使數組指針的值是 nil。
- slice? 和 map? 切片或映射中元素的個數,如果切片或映射的值是 nil,len(v) 值的長度是 0。
- string 字符串中字節的個數。
- channel? 通道緩沖區中未讀元素的個數,如果緩沖通道的值是 nil,len(v) 值的長度是 0。
輸出結果:
需要注意的是,slice、map? 和 channel? 必須先使用內置函數 make 初始化后,該類型的值才可以使用。
內置函數 ?cap:
內置函數 cap 返回值的容量,值的類型不同,值的容量含義也不同。
- array? 數組中元素的個數,數組的 cap(v)? 與 len(v) 相等。
- *array? 數組指針中元素的個數,數組指針的 cap(v)? 和 len(v) 相等。
- slice? 切片可以容納元素的最大長度,如果切片的值是 nil?,該切片 cap(v) 值的容量是 0。
- channel? 通道緩沖區的容量,如果通道的值是 nil?,該通道 cap(v) 值的容量是 0。
輸出結果:
內置函數 ?make:
內置函數 make? 僅限為 slice、map? 和 channel 分配內存并初始化。
make 第一個參數是類型,而不是值;第二個參數是可選(變長)參數,整型類型的值,返回值是該類型的值本身。
需要注意的是,第一個參數不同(不同類型),第二個參數的含義不同。
- slice 第一個參數是切片類型,第二個參數的含義是指定切片的長度。如果沒有傳遞第三個參數(整型類型的值),切片的容量等同于切片的長度,否則,切片的容量等同于第三個參數的值,需要注意的是,切片的容量必須不小于切片的長度。
- map 分配一個有足夠空間可以容納指定數量元素的空映射,第二個參數可以省略,如果省略第二個參數,將分配一個起始值 0。
- channel 指定緩沖區大小,初始化通道,如果第二個參數省略,或指定值為 0,該通道將被初始化為一個無緩沖通道。
內置函數 ?new:
內置函數 new? 也可以分配內存,與 make 的區別是,它僅分配內存,而未初始化。
和 make 相同,第一個參數是類型,而不是值;
和 make 不同,返回值是新分配的類型零值的指針。
內置函數 ?complex:
內置函數 complex? 將兩個浮點型的值構造為一個復合類型的值,需要注意的是,實部和虛部必須是相同類型,即都是 float32? 或 float64。
返回值是對應的復合類型,即 complex64? 對應 float32? 或 complex128? 對應 float64。
內置函數 ?real:
內置函數 real 用于返回復合類型的值的實部,返回值是對應的浮點數類型。
內置函數 ?imag:
內置函數 imag 用于返回復合類型的值的虛部,返回值是對應的浮點數類型。
注意:complex、real? 和 imag 三個內置函數,一般不常用,讀者朋友們只需簡單了解即可。
內置函數 ?close:
內置函數 close 關閉通道,被關閉的通道必須是一個雙向通道或僅支持發送的單向通道。
并且 close 應該由發送者執行,結果是在最后一個發送的值被接收后,關閉該通道。
通道被關閉后,任何該通道的接收者將返回成功而不會阻塞,接收者得到的返回值是該通道的類型零值和一個布爾類型的零值 false。
需要注意的是,不僅是關閉通道會返回 false?,空通道也會返回 false。
內置函數 ?panic:
內置函數 panic? 停止當前 goroutine? 正常執行,當一個函數 F? 調用 panic? 時,該函數 F 立即停止正常執行。
該函數 F? 通過 defer? 延遲調用的任意函數,仍然會執行,并將執行結果返回給 F 調用者。
對于 F? 的調用者 F2?,調用 F? 也會像調用 panic?,停止 F2? 的執行,并運行 F2? 通過 defer? 延遲調用的任意函數。以此類推,一直持續到當前 goroutine 中的所有函數都以相反的順序停止運行。
此時,程序以非 0 退出代碼終止運行。
以上終止程序運行的序列稱為“恐慌”,可以通過接下來我們要介紹的內置函數 recover 進行控制。
內置函數 ?recover:
內置函數 recover? 允許程序管理“恐慌”的 goroutine 的行為。
可以在 defer? 中調用 recover 恢復正常執行來停止“恐慌”,并且檢索導致“恐慌”的錯誤。
但是,如果在 defer? 之外調用 recover?,它不會恢復正常執行來停止“恐慌”。此種情況,recover? 的返回值是 nil?。此外,當前執行 recover? 的 goroutine? 未“恐慌”,或調用 panic(nil)? 時,recover? 的返回值也是 nil。
因此,我們可以通過 recover? 的返回值,判斷當前 goroutine 是否“恐慌”。
注意:此處講的在 defer? 中調用 recover?,是指在 defer? 本身中,而不是任何被 defer 調用的函數中。
內置函數 ?print:
內置函數 print 可以通過指定格式來格式化其參數,并將結果輸出。
內置函數 ?println:
內置函數 println? 可以通過指定格式來格式化其參數,并將結果輸出。與 print 的區別是,參數之間會添加空格,末尾會添加換行符。
注意:print? 和 println? 與標準庫 fmt? 中的 fmt.Print()? 和 fmt.Println()? 的區別是,前者是標準錯誤輸出,后者是標準輸出。在 Go 語言開發中,官方推薦使用標準庫 fmt 包,感興趣的讀者朋友們可以查閱相關資料進一步了解。
03 總結
本文我們介紹 Go 語言的內置函數,讀者朋友們需要重點掌握的內置函數是 len、cap、make、new、append、copy、delete、close、panic? 和 recover。