您好,登錄后才能下訂單哦!
這篇文章主要講解了“Go變量聲明方式有哪些”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Go變量聲明方式有哪些”吧!
Go提供了幾種基本但非必需的類型,比如切片,接口和通道。
Go簡單不是它的主要賣點,做為一門靜態(tài)語言,Go卻和很多動態(tài)腳本語言一樣得靈活是Go的主要賣點,節(jié)省內(nèi)存、程序啟動快和代碼執(zhí)行速度快合在一塊兒是Go的另一個主要賣點,Go是一門編譯型的和靜態(tài)的編程語言。 Go誕生于谷歌研究院
內(nèi)置并發(fā)編程支持:
使用協(xié)程(goroutine)做為基本的計算單元。輕松地創(chuàng)建協(xié)程。
使用通道(channel)來實現(xiàn)協(xié)程間的同步和通信。
內(nèi)置了映射(map)和切片(slice)類型。
支持多態(tài)(polymorphism)。
使用接口(interface)來實現(xiàn)裝盒(value boxing)和反射(reflection)。
支持指針。
支持函數(shù)閉包(closure)。
支持方法。
支持延遲函數(shù)調(diào)用(defer)。
支持類型內(nèi)嵌(type embedding)。
支持類型推斷(type deduction or type inference)。
內(nèi)存安全。
自動垃圾回收。
良好的代碼跨平臺性。
編譯時間的長短是開發(fā)愉悅度的一個重要因素。 編譯時間短是很多程序員喜歡Go的一個原因
## 運行g(shù)o程序 go run ## 打包go程序,生成可執(zhí)行文件 go build ## 來安裝一個第三方Go程序的最新版本,(至GOBIIN目錄) 在Go官方工具鏈1.16版本之前,對應(yīng)的命令是go get -u example.com/program(現(xiàn)在已經(jīng)被廢棄而不再推薦被使用了 go install ## 檢查可能的代碼邏輯錯誤 go vet ## 獲取網(wǎng)絡(luò)的依賴包,用拉添加、升級、降級或者刪除單個依賴,不如go mod tidy常用? go get -u ## 生成go.mod 文件,依賴到的模塊 go mod init Demo.go ## 掃描當前項目中的所有代碼來添加未被記錄的依賴至go.mod文件或從go.mod文件中刪除不再被使用的依賴 go mod tidy ## 格式化源文件代碼 go fmt Demo.go ## 運行單元和基準測試用例 go test ## 查看Go代碼庫包的文檔 go doc ## 運行g(shù)o help aSubCommand來查看一個子命令aSubCommand的幫助信息 go help
GOROOT是Go語言環(huán)境的安裝路徑,在安裝開發(fā)環(huán)境時已經(jīng)確定 GOPATH是當前項目工程的開發(fā)路徑,GOPATH可以有多個,每個GOPATH下的一般有三個包,pkg、src和bin,src用于存放項目工程的源代碼文件,pkg文件夾下的文件在編譯時自動生成,bin目錄下生成*.exe的可執(zhí)行文件。 PS:每一個GOPATH下都可以有pkg、src、bin三個文件夾,當設(shè)置多個GOPATH時,當前GOPATH的src源文件編譯結(jié)果和生成的可執(zhí)行文件會存儲在最近路徑的GOPATH的pkg和bin文件夾下,即當前GOPATH下,開發(fā)時在src目錄下新建目錄并建立源代碼文件,目錄名稱和源文件名稱可以不同,源文件內(nèi)第一行代碼package pkgName中的pkgName也可以和源文件所在文件夾名稱不同。但是,如果此包需要在其他包中使用,編譯器會報錯,建議package 后的名稱和文件所在文件夾的名稱相同。一般只有main函數(shù)所在的源文件下才會出現(xiàn)所在包和“package 包名”聲明的包名不同的情況
最終import 的包需要時package中寫的而不是目錄名,否則會報錯
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
const
、func
、import
、package
、type
和var
用來聲明各種代碼元素。
chan
、interface
、map
和struct
用做 一些組合類型的字面表示中。
break
、case
、continue
、default
、 else
、fallthrough
、for
、 goto
、if
、range
、 return
、select
和switch
用在流程控制語句中。 詳見基本流程控制語法。
defer
和go
也可以看作是流程控制關(guān)鍵字, 但它們有一些特殊的作用。詳見協(xié)程和延遲函數(shù)調(diào)用。
ps: uintptr、int以及uint類型的值的尺寸依賴于具體編譯器實現(xiàn)。 通常地,在64位的架構(gòu)上,int和uint類型的值是64位的;在32位的架構(gòu)上,它們是32位的。 編譯器必須保證uintptr類型的值的尺寸能夠存下任意一個內(nèi)存地址
在一個包含多個常量描述的常量聲明中,除了第一個常量描述,其它后續(xù)的常量描述都可以只有標識符部分。 Go編譯器將通過照抄前面最緊挨的一個完整的常量描述來自動補全不完整的常量描述。 比如,在編譯階段,編譯器會將下面的代碼
const ( X float32 = 3.14 Y // 這里必須只有一個標識符 Z // 這里必須只有一個標識符 A, B = "Go", "language" C, _ // 上一行中的空標識符是必需的(如果 // 上一行是一個不完整的常量描述)。 )
自動補全為
const ( X float32 = 3.14 Y float32 = 3.14 Z float32 = 3.14 A, B = "Go", "language" C, _ = "Go", "language" )
iota
是Go中預(yù)聲明(內(nèi)置)的一個特殊的有名常量。 iota
被預(yù)聲明為0
,但是它的值在編譯階段并非恒定。 當此預(yù)聲明的iota
出現(xiàn)在一個常量聲明中的時候,它的值在第n個常量描述中的值為n
(從0開始)。 所以iota
只對含有多個常量描述的常量聲明有意義。
iota
和常量描述自動補全相結(jié)合有的時候能夠給Go編程帶來很大便利。 比如,下面是一個使用了這兩個特性的例子
const ( Failed = iota - 1 // == -1 Unknown // == 0 Succeeded // == 1 ) const ( Readable = 1 << iota // == 1 Writable // == 2 Executable // == 4 )
可以看出,iota可以在狀態(tài)值常量的應(yīng)用上很方便,但是注意是在編譯時候使用哦
go語言中主要有下面兩種聲明方式
var ( lang, bornYear, compiled = "Go", 2007, true announceAt, releaseAt int = 2009, 2012 createdBy, website string )
注意,Go聲明的局部變量要被有效使用一次,包變量沒有限制,另外不支持其他語言所支持的連等賦值,如下圖:
var a, b int a = b = 123 // 語法錯誤
package main func main() { // 變量lang和year都為新聲明的變量。 lang, year := "Go language", 2007 // 這里,只有變量createdBy是新聲明的變量。 // 變量year已經(jīng)在上面聲明過了,所以這里僅僅 // 改變了它的值,或者說它被重新聲明了。 year, createdBy := 2009, "Google Research" // 這是一個純賦值語句。 lang, year = "Go", 2012 print(lang, "由", createdBy, "發(fā)明") print("并發(fā)布于", year, "年。") println() }
:=
這種方式聲明的還有個特點就是,短聲明語句中必須至少有一個新聲明的變量,可以支持前面部分聲明過的變量再繼續(xù)聲明賦值
分別為 func
函數(shù)名 參數(shù) 返回值 函數(shù)體(包含返回值或者不包含)
其他都好理解,有一點需要注意在Go中和其他語言不同之處,就是返回值如果匿名聲明,那么return 的時候需要明確返回變量或者某個值,如果是非匿名聲明,那么就可以只寫return
這個和其他語言還是有一點區(qū)別的,如果函數(shù)沒有返回值 ,那么return
就不用寫,Go不支持輸入?yún)?shù)默認值。每個返回結(jié)果的默認值是它的類型的零值。 比如,下面的函數(shù)在被調(diào)用時將打印出(和返回)0 false
func f() (x int, y bool) { println(x, y) // 0 false return } // 個人不是很懂這個,理解不了
三種基本的流程控制代碼塊:
if-else
條件分支代碼塊;
for
循環(huán)代碼塊;
switch-case
多條件分支代碼塊。
還有幾種和特定種類的類型相關(guān)的流程控制代碼塊:
容器類型相關(guān)的for-range
循環(huán)代碼塊。
接口類型相關(guān)的type-switch
多條件分支代碼塊。
通道類型相關(guān)的select-case
多分支代碼塊。
sync.WaitGroup
并發(fā)編程的一大任務(wù)就是要調(diào)度不同計算,控制它們對資源的訪問時段,以使數(shù)據(jù)競爭的情況不會發(fā)生。 此任務(wù)常稱為并發(fā)同步(或者數(shù)據(jù)同步)。Go支持幾種并發(fā)同步技術(shù),先學(xué)習(xí)最簡單的一種,sync
標準庫中的WaitGroup
來同步主協(xié)程和創(chuàng)建的協(xié)程
WaitGroup
類型有三個方法(特殊的函數(shù),將在以后的文章中詳解):Add
、Done
和Wait
。 此類型將在后面的某篇文章中詳細解釋,目前我們可以簡單地認為:
Add
方法用來注冊新的需要完成的任務(wù)數(shù)。
Done
方法用來通知某個任務(wù)已經(jīng)完成了。
一個Wait
方法調(diào)用將阻塞(等待)到所有任務(wù)都已經(jīng)完成之后才繼續(xù)執(zhí)行其后的語句
package main import ( "log" "math/rand" "time" "sync" ) var wg sync.WaitGroup func SayGreetings(greeting string, times int) { for i := 0; i < times; i++ { log.Println(greeting) d := time.Second * time.Duration(rand.Intn(5)) / 2 time.Sleep(d) } wg.Done() // 通知當前任務(wù)已經(jīng)完成。 } func main() { rand.Seed(time.Now().UnixNano()) log.SetFlags(0) wg.Add(2) // 注冊兩個新任務(wù)。 go SayGreetings("hi!", 10) go SayGreetings("hello!", 10) wg.Wait() // 阻塞在這里,直到所有任務(wù)都已完成。 }
可以看到一個活動中的協(xié)程可以處于兩個狀態(tài):運行狀態(tài)和阻塞狀態(tài)。一個協(xié)程可以在這兩個狀態(tài)之間切換
編譯器采納了一種被稱為M-P-G模型的算法來實現(xiàn)協(xié)程調(diào)度。 其中,M表示系統(tǒng)線程,P表示邏輯處理器(并非上述的邏輯CPU),G表示協(xié)程。 大多數(shù)的調(diào)度工作是通過邏輯處理器(P)來完成的。 邏輯處理器像一個監(jiān)工一樣通過將不同的處于運行狀態(tài)協(xié)程(G)交給不同的系統(tǒng)線程(M)來執(zhí)行。 一個協(xié)程在同一時刻只能在一個系統(tǒng)線程中執(zhí)行。一個執(zhí)行中的協(xié)程運行片刻后將自發(fā)地脫離讓出一個系統(tǒng)線程,從而使得其它處于等待子狀態(tài)的協(xié)程得到執(zhí)行機會。
感謝各位的閱讀,以上就是“Go變量聲明方式有哪些”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Go變量聲明方式有哪些這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。