您好,登錄后才能下訂單哦!
本篇內容介紹了“Go語言技術怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
Go提供了幾種基本但非必需的類型,比如切片,接口和通道。
Go簡單不是它的主要賣點,做為一門靜態語言,Go卻和很多動態腳本語言一樣得靈活是Go的主要賣點,節省內存、程序啟動快和代碼執行速度快合在一塊兒是Go的另一個主要賣點,Go是一門編譯型的和靜態的編程語言。Go誕生于谷歌研究院
內置并發編程支持:
使用協程(goroutine)做為基本的計算單元。輕松地創建協程。
使用通道(channel)來實現協程間的同步和通信。
內置了映射(map)和切片(slice)類型。
支持多態(polymorphism)。
使用接口(interface)來實現裝盒(value boxing)和反射(reflection)。
支持指針。
支持函數閉包(closure)。
支持方法。
支持延遲函數調用(defer)。
支持類型內嵌(type embedding)。
支持類型推斷(type deduction or type inference)。
內存安全。
自動垃圾回收。
良好的代碼跨平臺性。
編譯時間的長短是開發愉悅度的一個重要因素。編譯時間短是很多程序員喜歡Go的一個原因
## 運行go程序
go run
## 打包go程序,生成可執行文件
go build
## 來安裝一個第三方Go程序的最新版本,(至GOBIIN目錄) 在Go官方工具鏈1.16版本之前,對應的命令是go get -u example.com/program(現在已經被廢棄而不再推薦被使用了
go install
## 檢查可能的代碼邏輯錯誤
go vet
## 獲取網絡的依賴包,用拉添加、升級、降級或者刪除單個依賴,不如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
## 運行go help aSubCommand來查看一個子命令aSubCommand的幫助信息
go help
GOROOT是Go語言環境的安裝路徑,在安裝開發環境時已經確定 GOPATH是當前項目工程的開發路徑,GOPATH可以有多個,每個GOPATH下的一般有三個包,pkg、src和bin,src用于存放項目工程的源代碼文件,pkg文件夾下的文件在編譯時自動生成,bin目錄下生成*.exe的可執行文件。PS:每一個GOPATH下都可以有pkg、src、bin三個文件夾,當設置多個GOPATH時,當前GOPATH的src源文件編譯結果和生成的可執行文件會存儲在最近路徑的GOPATH的pkg和bin文件夾下,即當前GOPATH下,開發時在src目錄下新建目錄并建立源代碼文件,目錄名稱和源文件名稱可以不同,源文件內第一行代碼package pkgName中的pkgName也可以和源文件所在文件夾名稱不同。但是,如果此包需要在其他包中使用,編譯器會報錯,建議package 后的名稱和文件所在文件夾的名稱相同。一般只有main函數所在的源文件下才會出現所在包和“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
也可以看作是流程控制關鍵字, 但它們有一些特殊的作用。詳見協程和延遲函數調用。
ps: uintptr、int以及uint類型的值的尺寸依賴于具體編譯器實現。通常地,在64位的架構上,int和uint類型的值是64位的;在32位的架構上,它們是32位的。編譯器必須保證uintptr類型的值的尺寸能夠存下任意一個內存地址
在一個包含多個常量描述的常量聲明中,除了第一個常量描述,其它后續的常量描述都可以只有標識符部分。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中預聲明(內置)的一個特殊的有名常量。iota
被預聲明為0
,但是它的值在編譯階段并非恒定。當此預聲明的iota
出現在一個常量聲明中的時候,它的值在第n個常量描述中的值為n
(從0開始)。所以iota
只對含有多個常量描述的常量聲明有意義。
iota
和常量描述自動補全相結合有的時候能夠給Go編程帶來很大便利。比如,下面是一個使用了這兩個特性的例子
const (
Failed = iota - 1 // == -1
Unknown // == 0
Succeeded // == 1
)
const (
Readable = 1 << iota // == 1
Writable // == 2
Executable // == 4
)
可以看出,iota可以在狀態值常量的應用上很方便,但是注意是在編譯時候使用哦
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已經在上面聲明過了,所以這里僅僅
// 改變了它的值,或者說它被重新聲明了。
year, createdBy := 2009, "Google Research"
// 這是一個純賦值語句。
lang, year = "Go", 2012
print(lang, "由", createdBy, "發明")
print("并發布于", year, "年。")
println()
}
:=
這種方式聲明的還有個特點就是,短聲明語句中必須至少有一個新聲明的變量,可以支持前面部分聲明過的變量再繼續聲明賦值
分別為 func
函數名 參數 返回值 函數體(包含返回值或者不包含)
其他都好理解,有一點需要注意在Go中和其他語言不同之處,就是返回值如果匿名聲明,那么return 的時候需要明確返回變量或者某個值,如果是非匿名聲明,那么就可以只寫return
這個和其他語言還是有一點區別的,如果函數沒有返回值 ,那么return
就不用寫,Go不支持輸入參數默認值。每個返回結果的默認值是它的類型的零值。比如,下面的函數在被調用時將打印出(和返回)0 false
func f() (x int, y bool) {
println(x, y) // 0 false
return
}
// 個人不是很懂這個,理解不了
三種基本的流程控制代碼塊:
if-else
條件分支代碼塊;
for
循環代碼塊;
switch-case
多條件分支代碼塊。
還有幾種和特定種類的類型相關的流程控制代碼塊:
容器類型相關的for-range
循環代碼塊。
接口類型相關的type-switch
多條件分支代碼塊。
通道類型相關的select-case
多分支代碼塊。
sync.WaitGroup
并發編程的一大任務就是要調度不同計算,控制它們對資源的訪問時段,以使數據競爭的情況不會發生。此任務常稱為并發同步(或者數據同步)。Go支持幾種并發同步技術,先學習最簡單的一種,sync
標準庫中的WaitGroup
來同步主協程和創建的協程
WaitGroup
類型有三個方法(特殊的函數,將在以后的文章中詳解):Add
、Done
和Wait
。此類型將在后面的某篇文章中詳細解釋,目前我們可以簡單地認為:
Add
方法用來注冊新的需要完成的任務數。
Done
方法用來通知某個任務已經完成了。
一個Wait
方法調用將阻塞(等待)到所有任務都已經完成之后才繼續執行其后的語句
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() // 通知當前任務已經完成。
}
func main() {
rand.Seed(time.Now().UnixNano())
log.SetFlags(0)
wg.Add(2) // 注冊兩個新任務。
go SayGreetings("hi!", 10)
go SayGreetings("hello!", 10)
wg.Wait() // 阻塞在這里,直到所有任務都已完成。
}
可以看到一個活動中的協程可以處于兩個狀態:運行狀態和阻塞狀態。一個協程可以在這兩個狀態之間切換
編譯器采納了一種被稱為M-P-G模型的算法來實現協程調度。其中,M表示系統線程,P表示邏輯處理器(并非上述的邏輯CPU),G表示協程。大多數的調度工作是通過邏輯處理器(P)來完成的。邏輯處理器像一個監工一樣通過將不同的處于運行狀態協程(G)交給不同的系統線程(M)來執行。一個協程在同一時刻只能在一個系統線程中執行。一個執行中的協程運行片刻后將自發地脫離讓出一個系統線程,從而使得其它處于等待子狀態的協程得到執行機會,如下圖,P可以理解為總司令,G是程序寫好的邏輯協程,而M是具體的系統線程執行器
“Go語言技術怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。