Go語言的文件名、標(biāo)識(shí)符、關(guān)鍵字和包基礎(chǔ)教程
1、文件名、關(guān)鍵字與標(biāo)識(shí)符
1.1、名稱與標(biāo)識(shí)符
Go 語言中的源文件通常以 .go
為擴(kuò)展名,并存儲(chǔ)在計(jì)算機(jī)上。這些文件的命名完全由小寫字母構(gòu)成,例如 scanner.go
。對(duì)于包含多個(gè)詞的文件名,通常使用下劃線 _
來連接各部分,如 scanner_test.go
,并且文件名中不會(huì)包含空格或其他特殊字符。
在 Go 語言的環(huán)境中,源文件的大小并沒有限制,一個(gè)文件可以包含從幾行到數(shù)千行的代碼。
在 Go 代碼中,幾乎所有的元素都需要用到名稱或標(biāo)識(shí)符,而且這些標(biāo)識(shí)符對(duì)大小寫敏感,這一點(diǎn)與 C 系列語言相似。有效的標(biāo)識(shí)符應(yīng)該以字母(支持任何 UTF-8 編碼的字符)或下劃線 _
開頭,后接任意數(shù)量的字母、數(shù)字或下劃線,例如:X56
、group1
、_x23
、i
、??12
。
不過,有些標(biāo)識(shí)符是無效的,包括:
1ab
:以數(shù)字開頭是不允許的。case
:因?yàn)樗?Go 語言的關(guān)鍵字。a+b
:包含運(yùn)算符,這是不被允許的。
特別地,下劃線 _
被稱為空白標(biāo)識(shí)符,它在 Go 語言中有特殊用途??梢詫⑷魏晤愋偷闹蒂x給它,但賦值后的結(jié)果不會(huì)被使用,也不能通過它來進(jìn)行進(jìn)一步的變量賦值或計(jì)算。
此外,在 Go 代碼中,有時(shí)候你會(huì)遇到?jīng)]有明確名稱的變量、類型或方法,這些通常被稱為匿名變量。使用匿名變量可以在某些場景下提升代碼的靈活性,盡管它們不是編寫 Go 程序的必需元素。
1.2、關(guān)鍵字
Go 語言定義了 25 個(gè)關(guān)鍵字或保留字,這些關(guān)鍵字在編寫 Go 代碼時(shí)具有特殊的語義,不能用作標(biāo)識(shí)符。這些關(guān)鍵字涵蓋了控制結(jié)構(gòu)、數(shù)據(jù)類型定義、以及包的管理等多個(gè)方面。下面是 Go 語言中所有的關(guān)鍵字列表:
控制流關(guān)鍵字:
break
: 用于中斷當(dāng)前循環(huán);case
: 在switch
語句中,用于定義一個(gè)分支;continue
: 跳過當(dāng)前循環(huán)的剩余部分,繼續(xù)執(zhí)行下一次循環(huán);default
: 在switch
或select
語句中,定義默認(rèn)分支;defer
: 延遲執(zhí)行一個(gè)函數(shù)直到包含它的函數(shù)執(zhí)行結(jié)束;else
: 與if
一起使用,定義一個(gè)條件不滿足時(shí)執(zhí)行的代碼塊;fallthrough
: 在switch
中強(qiáng)制執(zhí)行下一個(gè)case
;for
: 定義循環(huán);goto
: 跳轉(zhuǎn)到指定的標(biāo)簽;if
: 條件語句;return
: 從函數(shù)中返回值;select
: 用于處理多個(gè)通道的接收操作;switch
: 條件分支語句;
數(shù)據(jù)類型及結(jié)構(gòu)關(guān)鍵字:
chan
: 用于定義通道類型;const
: 定義常量;func
: 定義函數(shù);interface
: 定義接口;map
: 定義映射類型;package
: 定義包名;range
: 用于迭代數(shù)組、切片、字符串、映射或通道;struct
: 定義結(jié)構(gòu)體;type
: 定義一個(gè)新的類型;var
: 定義變量。
這些關(guān)鍵字是 Go 語言的基礎(chǔ)組成部分,理解它們的用途和語義對(duì)于編寫有效和高效的 Go 程序至關(guān)重要。
之所以刻意地將 Go 代碼中的關(guān)鍵字保持的這么少,是為了簡化在編譯過程第一步中的代碼解析。和其它語言一樣,關(guān)鍵字不能夠作標(biāo)識(shí)符使用。
Go 語言除了有25個(gè)關(guān)鍵字外,還提供了36個(gè)預(yù)定義的標(biāo)識(shí)符,這些包括了一系列基本數(shù)據(jù)類型的名稱和一些重要的內(nèi)置函數(shù)。這些預(yù)定義標(biāo)識(shí)符是 Go 語言標(biāo)準(zhǔn)庫的一部分,它們提供了操作基本數(shù)據(jù)類型和執(zhí)行關(guān)鍵操作的能力。
這里是 Go 語言中的 36 個(gè)預(yù)定義標(biāo)識(shí)符:append
、bool
、byte
、cap
、close
、complex
、complex64
、complex128
、copy
、false
、float32
、float64
、imag
、int
、int8
、int16
、int32
、int64
、iota
、len
、make
、new
、nil
、panic
、print
、println
、real
、recover
、string
、true
、uint
、uint8
、uint16
、uint32
、uint64
、uintptr
。
1.3、符號(hào)
程序一般由關(guān)鍵字、常量、變量、運(yùn)算符、類型和函數(shù)組成。
程序中可能會(huì)使用到這些分隔符:括號(hào) ()
,中括號(hào) []
和大括號(hào) {}
。
程序中可能會(huì)使用到這些標(biāo)點(diǎn)符號(hào):.
、,
、;
、:
和 …
。
程序的代碼通過語句來實(shí)現(xiàn)結(jié)構(gòu)化。每個(gè)語句不需要像 C 家族中的其它語言一樣以分號(hào) ;
結(jié)尾,因?yàn)檫@些工作都將由 Go 編譯器自動(dòng)完成。
如果你打算將多個(gè)語句寫在同一行,它們則必須使用 ;
人為區(qū)分,但在實(shí)際開發(fā)中我們并不鼓勵(lì)這種做法。
2、Go 包
2.1、Go 語言包的概念
包在 Go 語言中用于結(jié)構(gòu)化代碼,類似于其他編程語言中的類庫或命名空間。每個(gè) Go 源文件都屬于一個(gè)特定的包,并且一個(gè)包可以由多個(gè) .go
擴(kuò)展名的源文件組成。通常情況下,文件名和包名不相同。
在源文件的非注釋第一行,必須明確指出該文件屬于哪個(gè)包,例如 package main
。package main
定義了一個(gè)可獨(dú)立執(zhí)行的程序,每個(gè) Go 應(yīng)用程序必須包含一個(gè)名為 main
的包。
盡管一個(gè)應(yīng)用程序可能包含多個(gè)不同的包,但即使只使用 main
包,也不必將所有代碼寫在一個(gè)龐大的文件中??梢詫⒋a分散到幾個(gè)較小的文件中,每個(gè)文件的第一行使用 package main
表明它們都屬于 main
包。如果編譯的包名不是 main
,如 pack1
,則編譯產(chǎn)生的是 pack1.a
對(duì)象文件而不是可執(zhí)行程序。值得注意的是,所有包名應(yīng)使用小寫字母。
2.2、Go 語言的標(biāo)準(zhǔn)庫
Go 語言的安裝包中包括了一個(gè)豐富的標(biāo)準(zhǔn)庫,這是一組預(yù)先編譯好的包,可以直接在你的程序中使用。標(biāo)準(zhǔn)庫的具體位置取決于操作系統(tǒng)和處理器架構(gòu)。
例如,在 Windows 系統(tǒng)上,標(biāo)準(zhǔn)庫位于 Go 安裝根目錄下的 pkg\windows_386
子目錄中;在 Linux 系統(tǒng)上,如果是 64 位,則在 pkg\linux_amd64
子目錄中,32 位系統(tǒng)則在 linux_386
目錄中。通常情況下,標(biāo)準(zhǔn)庫存放在 $GOROOT/pkg/$GOOS_$GOARCH/
目錄下。
標(biāo)準(zhǔn)庫中包含了許多實(shí)用的包,如 fmt
和 os
。除了使用這些現(xiàn)成的包,你也可以創(chuàng)建自己的包以滿足特定的功能需求。
為了構(gòu)建程序,所有相關(guān)的包和文件必須按照正確的順序編譯,這個(gè)順序通常由包的依賴關(guān)系決定。在 Go 語言中,屬于同一個(gè)包的所有源文件必須一起編譯,因?yàn)橐粋€(gè)包在編譯時(shí)被視為一個(gè)單獨(dú)的編譯單元。按照慣例,每個(gè)目錄中通常只包含一個(gè)包,以保持結(jié)構(gòu)的清晰和管理的簡單。
2.3、Go 語言包依賴與編譯策略
在 Go 語言的包模型中,對(duì)某個(gè)包進(jìn)行更改或重新編譯后,所有引用該包的客戶端程序必須重新編譯,以確保所有的依賴都是最新的。Go 的編譯器采用了一種顯式依賴關(guān)系的機(jī)制,這種機(jī)制極大地加快了編譯速度。
編譯過程中,Go 編譯器從后綴名為 .o
的對(duì)象文件中提取傳遞依賴類型的信息。這意味著,編譯器在編譯一個(gè)文件時(shí),只需引用直接依賴的 .o
文件,而不是所有相關(guān)的源文件。例如:
- 假設(shè)有三個(gè)文件:
A.go
、B.go
和C.go
,其中A.go
依賴于B.go
,而B.go
依賴于C.go
。 - 編譯順序應(yīng)為先編譯
C.go
,再編譯B.go
,最后編譯A.go
。 - 在編譯
A.go
時(shí),編譯器只需讀取B.o
文件。盡管B.go
依賴C.go
,編譯A.go
并不直接需要C.o
,因?yàn)樗斜匾男畔⒍家呀?jīng)在B.o
中。
這種編譯機(jī)制不僅簡化了依賴管理,也使得編譯大型項(xiàng)目更加高效。通過這種方式,Go 語言能夠提供快速的編譯速度,同時(shí)保持代碼的模塊化和高度組織化。
2.4、每一段代碼只會(huì)被編譯一次
一個(gè) Go 程序是通過 import
關(guān)鍵字將一組包鏈接在一起。
import "fmt"
告訴 Go 編譯器這個(gè)程序需要使用 fmt
包(的函數(shù),或其他元素),fmt
包實(shí)現(xiàn)了格式化 IO(輸入/輸出)的函數(shù)。包名被封閉在半角雙引號(hào) ""
中。如果你打算從已編譯的包中導(dǎo)入并加載公開聲明的方法,不需要插入已編譯包的源代碼。
如果需要多個(gè)包,它們可以被分別導(dǎo)入:
import "fmt" import "os"
或:
import "fmt"; import "os"
但是還有更短且更優(yōu)雅的方法(被稱為因式分解關(guān)鍵字,該方法同樣適用于 const
、var
和 type
的聲明或定義):
import ( "fmt" "os" )
它甚至還可以更短的形式,但使用 gofmt 后將會(huì)被強(qiáng)制換行:
import ("fmt"; "os")
當(dāng)你導(dǎo)入多個(gè)包時(shí),最好按照字母順序排列包名,這樣做更加清晰易讀。
如果包名不是以 .
或 /
開頭,如 "fmt"
或者 "container/list"
,則 Go 會(huì)在全局文件進(jìn)行查找;如果包名以 ./
開頭,則 Go 會(huì)在相對(duì)目錄中查找;如果包名以 /
開頭(在 Windows 下也可以這樣使用),則會(huì)在系統(tǒng)的絕對(duì)路徑中查找。
導(dǎo)入包即等同于包含了這個(gè)包的所有的代碼對(duì)象。
除了符號(hào) _
,包中所有代碼對(duì)象的標(biāo)識(shí)符必須是唯一的,以避免名稱沖突。但是相同的標(biāo)識(shí)符可以在不同的包中使用,因?yàn)榭梢允褂冒麃韰^(qū)分它們。
包通過下面這個(gè)被編譯器強(qiáng)制執(zhí)行的規(guī)則來決定是否將自身的代碼對(duì)象暴露給外部文件:
2.5、Go 語言的標(biāo)識(shí)符可見性與包管理
在 Go 語言中,標(biāo)識(shí)符(包括常量、變量、類型、函數(shù)名、結(jié)構(gòu)字段等)的首字母大小寫決定了其可見性和可訪問性。如果標(biāo)識(shí)符以大寫字母開頭(如 Group1
),則該標(biāo)識(shí)符的對(duì)象可以被外部包訪問,這相當(dāng)于其他面向?qū)ο笳Z言中的 public
。這種機(jī)制被稱為導(dǎo)出。值得注意的是,大寫字母可以是任何 Unicode 編碼的字符,不限于 ASCII 碼。
相反,如果標(biāo)識(shí)符以小寫字母開頭,則它對(duì)包外是不可見的,類似于面向?qū)ο笳Z言中的 private
。這種標(biāo)識(shí)符僅在其所屬的包內(nèi)部可見并可用。
例如,假設(shè)在包 pack1
中有一個(gè)變量或函數(shù)名為 Thing
(以大寫 T
開頭,因此可被導(dǎo)出),在其他包中通過導(dǎo)入 pack1
可以訪問 Thing
,使用方式如下:pack1.Thing
。在這里,pack1
作為命名空間,是不可以省略的。
包的這種命名空間功能有助于避免名稱沖突。例如,pack1.Thing
和 pack2.Thing
可以清晰地區(qū)分屬于不同包的同名變量或函數(shù)。
2.6、使用包的別名
在 Go 中,你可以通過為包指定別名來解決包名沖突或簡化代碼。例如,你可以這樣導(dǎo)入 fmt
包并為其設(shè)置別名:
package main import fm "fmt" func main() { fm.Println("hello, world") }
2.7、包的聲明和初始化
在 Go 中,你可以在導(dǎo)入包之后,在包級(jí)別定義或聲明常量(const
)、變量(var
)和類型(type
)。這些定義的作用域是全局的,可在整個(gè)包中被訪問。之后,可以聲明一個(gè)或多個(gè)函數(shù)(func
)來進(jìn)行具體的邏輯操作。這樣的結(jié)構(gòu)使得代碼既清晰又易于管理。
Ps:如果你導(dǎo)入了一個(gè)包卻沒有在代碼中使用它,Go 編譯器會(huì)拋出錯(cuò)誤,例如 imported and not used: os
。這反映了 Go 的設(shè)計(jì)哲學(xué):“沒有不必要的代碼!”
總結(jié)
到此這篇關(guān)于Go語言的文件名、標(biāo)識(shí)符、關(guān)鍵字和包的文章就介紹到這了,更多相關(guān)Go語言文件名、標(biāo)識(shí)符、關(guān)鍵字和包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang?實(shí)現(xiàn)Redis?協(xié)議解析器的解決方案
這篇文章主要介紹了Golang???實(shí)現(xiàn)?Redis?協(xié)議解析器,本文將分別介紹Redis 通信協(xié)議 以及 協(xié)議解析器 的實(shí)現(xiàn),若您對(duì)協(xié)議有所了解可以直接閱讀協(xié)議解析器部分,需要的朋友可以參考下2022-10-10關(guān)于go語言載入json可能遇到的一個(gè)坑
Go 語言從新手到大神,每個(gè)人多少都會(huì)踩一些坑,那么下面這篇文章主要給大家介紹了關(guān)于go語言載入json可能遇到的一個(gè)坑,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07golang實(shí)現(xiàn)ping命令的完整代碼
這篇文章給大家介紹了如何使用golang實(shí)現(xiàn)ping命令,文中給大家介紹了完整的實(shí)現(xiàn)代碼,并有詳細(xì)的圖文講解,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02解決Golang小數(shù)float64在實(shí)際工程中加減乘除的精度問題
這篇文章主要介紹了解決Golang小數(shù)float64在實(shí)際工程中加減乘除的精度問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03Go來合并兩個(gè)csv的實(shí)現(xiàn)示例
本文主要介紹了Go來合并兩個(gè)csv的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10