golang 簡介
很久以前,有一個IT公司简十,這公司有個傳統(tǒng)邦泄,允許員工擁有20%自由時間來開發(fā)實驗性項目仔燕。在2007的某一天,公司的幾個大牛葡秒,正在用c++開發(fā)一些比較繁瑣但是核心的工作姻乓,主要包括龐大的分布式集群嵌溢,大牛覺得很鬧心,后來c++委員會來他們公司演講蹋岩,說c++將要添加大概35種新特性赖草。這幾個大牛的其中一個人,名為:Rob Pike剪个,聽后心中一萬個xxx飄過秧骑,“c++特性還不夠多嗎?簡化c++應該更有成就感吧”禁偎。于是乎腿堤,Rob Pike和其他幾個大牛討論了一下阀坏,怎么解決這個問題如暖,過了一會,Rob Pike說要不我們自己搞個語言吧忌堂,名字叫“go”盒至,非常簡短,容易拼寫士修。其他幾位大牛就說好啊枷遂,然后他們找了塊白板,在上面寫下希望能有哪些功能(詳見文尾)棋嘲。接下來的時間里酒唉,大牛們開心的討論設計這門語言的特性,經(jīng)過漫長的歲月沸移,他們決定痪伦,以c語言為原型,以及借鑒其他語言的一些特性雹锣,來解放程序員网沾,解放自己,然后在2009年蕊爵,go語言誕生辉哥。
思想
Less can be more 大道至簡,小而蘊真 讓事情變得復雜很容易,讓事情變得簡單才難 深刻的工程文化
優(yōu)點
- 自帶gc攒射。
- 靜態(tài)編譯醋旦,編譯好后,扔服務器直接運行会放。
- 簡單的思想浑度,沒有繼承,多態(tài)鸦概,類等箩张。
- 豐富的庫和詳細的開發(fā)文檔甩骏。
- 語法層支持并發(fā),和擁有同步并發(fā)的channel類型先慷,使并發(fā)開發(fā)變得非常方便饮笛。
- 簡潔的語法,提高開發(fā)效率论熙,同時提高代碼的閱讀性和可維護性福青。
- 超級簡單的交叉編譯,僅需更改環(huán)境變量脓诡。(花了我兩天時間編譯一個imagemagick到arm平臺)
- 內(nèi)含完善无午、全面的軟件工程工具。Go語言自帶的命令和工具相當?shù)貜姶笞Q琛Mㄟ^它們宪迟,我們可以很輕松地完成
- Go語言程序的獲取、編譯交惯、測試次泽、安裝、運行席爽、運行分析等一系列工作意荤,這幾乎涉及了開發(fā)和維護一個軟件的所有環(huán)節(jié)。
Go 語言是谷歌 2009 年首次推出并在 2012 年正式發(fā)布的一種全新的編程語言只锻,可以在不損失應用程序性能的情況下降低代碼的復雜性玖像。谷歌首席軟件工程師羅布派克(Rob Pike)說:我們之所以開發(fā) Go,是因為過去10多年間軟件開發(fā)的難度令人沮喪齐饮。Google 對 Go 寄予厚望捐寥,其設計是讓軟件充分發(fā)揮多核心處理器同步多工的優(yōu)點,并可解決面向?qū)ο蟪绦蛟O計的麻煩沈矿。它具有現(xiàn)代的程序語言特色上真,如垃圾回收,幫助開發(fā)者處理瑣碎但重要的內(nèi)存管理問題羹膳。Go 的速度也非乘ィ快,幾乎和 C 或 C++ 程序一樣快陵像,且能夠快速開發(fā)應用程序就珠。
Go語言的主要特征:
- 自動立即回收。
- 更豐富的內(nèi)置類型醒颖。
- 函數(shù)多返回值妻怎。
- 錯誤處理。
- 匿名函數(shù)和閉包泞歉。
- 類型和接口逼侦。
- 并發(fā)編程匿辩。
- 反射。
- 語言交互性榛丢。
Golang文件名:
所有的go源碼都是以 ".go" 結(jié)尾铲球。
Go語言命名:
1.Go的函數(shù)、變量晰赞、常量稼病、自定義類型、包(package)
的命名方式遵循以下規(guī)則:
1)首字符可以是任意的Unicode字符或者下劃線
2)剩余字符可以是Unicode字符掖鱼、下劃線然走、數(shù)字
3)字符長度不限
2.Go只有25個關鍵字
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
3.Go還有37個保留字
Constants: true false iota nil
Types: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
Functions: make len cap new append copy close delete
complex real imag
panic recover
4.可見性:
1)聲明在函數(shù)內(nèi)部,是函數(shù)的本地值戏挡,類似private
2)聲明在函數(shù)外部芍瑞,是對當前包可見(包內(nèi)所有.go文件都可見)的全局值,類似protect
3)聲明在函數(shù)外部且首字母大寫是所有包可見的全局值,類似public
Go語言聲明:
有四種主要聲明方式:
var(聲明變量), const(聲明常量), type(聲明類型) ,func(聲明函數(shù))增拥。
Go的程序是保存在多個.go文件中啄巧,文件的第一行就是package XXX聲明寻歧,用來說明該文件屬于哪個包(package)掌栅,package聲明下來就是import聲明,再下來是類型码泛,變量猾封,常量,函數(shù)的聲明噪珊。
Go項目構建及編譯
一個Go工程中主要包含以下三個目錄:
src:源代碼文件
pkg:包文件
bin:相關bin文件
1: 建立工程文件夾 goproject
2: 在工程文件夾中建立src,pkg,bin文件夾
3: 在GOPATH中添加projiect路徑 例 e:/goproject
4: 如工程中有自己的包examplepackage晌缘,那在src文件夾下建立以包名命名的文件夾 例 examplepackage
5:在src文件夾下編寫主程序代碼代碼 goproject.go
6:在examplepackage文件夾中編寫 examplepackage.go 和 包測試文件 examplepackage_test.go
7:編譯調(diào)試包
go build examplepackage
go test examplepackage
go install examplepackage
這時在pkg文件夾中可以發(fā)現(xiàn)會有一個相應的操作系統(tǒng)文件夾如windows_386z, 在這個文件夾中會有examplepackage文件夾,在該文件中有examplepackage.a文件
8:編譯主程序
go build goproject.go
成功后會生成goproject.exe文件
至此一個Go工程編輯成功痢站。
1.建立工程文件夾 go
$ pwd
/Users/***/Desktop/go
2: 在工程文件夾中建立src,pkg,bin文件夾
$ ls
bin conf pkg src
3: 在GOPATH中添加projiect路徑
$ go env
GOPATH="/Users/liupengjie/Desktop/go"
4: 那在src文件夾下建立以自己的包 example 文件夾
$ cd src/
$ mkdir example
5:在src文件夾下編寫主程序代碼代碼 goproject.go
6:在example文件夾中編寫 example.go 和 包測試文件 example_test.go
example.go 寫入如下代碼:
package example
func add(a, b int) int {
return a + b
}
func sub(a, b int) int {
return a - b
}
example_test.go 寫入如下代碼:
package example
import (
"testing"
)
func TestAdd(t *testing.T) {
r := add(2, 4)
if r != 6 {
t.Fatalf("add(2, 4) error, expect:%d, actual:%d", 6, r)
}
t.Logf("test add succ")
}
7:編譯調(diào)試包
$ go build example
$ go test example
ok example 0.013s
$ go install example
$ ls /Users/***/Desktop/go/pkg/
darwin_amd64
$ ls /Users/***/Desktop/go/pkg/darwin_amd64/
example.a
8:編譯主程序
oproject.go 寫入如下代碼:
package main
import (
"fmt"
)
func main(){
fmt.Println("go project test")
}
$ go build goproject.go
$ ls
example goproject.go goproject
成功后會生成goproject文件
至此一個Go工程編輯成功磷箕。
運行該文件:
$ ./goproject
go project test
go 編譯問題
golang的編譯使用命令 go build , go install;除非僅寫一個main函數(shù),否則還是準備好目錄結(jié)構阵难;
GOPATH=工程根目錄岳枷;其下應創(chuàng)建src,pkg呜叫,bin目錄空繁,bin目錄中用于生成可執(zhí)行文件,pkg目錄中用于生成.a文件朱庆;
golang中的import name盛泡,實際是到GOPATH中去尋找name.a, 使用時是該name.a的源碼中生命的package 名字;這個在前面已經(jīng)介紹過了娱颊。
注意點:
- 系統(tǒng)編譯時 go install abc_name時傲诵,系統(tǒng)會到GOPATH的src目錄中尋找abc_name目錄凯砍,然后編譯其下的go文件;
- 同一個目錄中所有的go文件的package聲明必須相同拴竹,所以main方法要單獨放一個文件果覆,否則在eclipse和liteide中都會報錯;
編譯報錯如下:(假設test目錄中有個main.go 和mymath.go,其中main.go聲明package為main殖熟,mymath.go聲明packag 為test);
$ go install test
can't load package: package test: found packages main (main.go) and test (mymath.go) in /home/wanjm/go/src/test
報錯說 不能加載package test(這是命令行的參數(shù))局待,因為發(fā)現(xiàn)了兩個package,分別時main.go 和 mymath.go; - 對于main方法菱属,只能在bin目錄下運行 go build path_tomain.go; 可以用-o參數(shù)指出輸出文件名钳榨;
- 可以添加參數(shù) go build -gcflags "-N -l" ****,可以更好的便于gdb;詳細參見 http://golang.org/doc/gdb
- gdb全局變量主一點纽门。 如有全局變量 a薛耻;則應寫為 p 'main.a';注意但引號不可少赏陵;
golang內(nèi)置類型和函數(shù)
- 內(nèi)置類型: (值類型)
bool
int(32 or 64), int8, int16, int32, int64
uint(32 or 64), uint8(byte), uint16, uint32, uint64
float32, float64
string
complex64, complex128
array -- 固定長度的數(shù)組
- 引用類型:(指針類型)
slice -- 序列數(shù)組(最常用)
map -- 映射
chan -- 管道
- 內(nèi)置函數(shù)
Go 語言擁有一些不需要進行導入操作就可以使用的內(nèi)置函數(shù)饼齿。它們有時可以針對不同的類型進行操作,例如:len蝙搔、cap 和 append缕溉,或必須用于系統(tǒng)級的操作,例如:panic吃型。因此证鸥,它們需要直接獲得編譯器的支持。
append -- 用來追加元素到數(shù)組勤晚、slice中,返回修改后的數(shù)組枉层、slice
close -- 主要用來關閉channel
delete -- 從map中刪除key對應的value
panic -- 停止常規(guī)的goroutine (panic和recover:用來做錯誤處理)
recover -- 允許程序定義goroutine的panic動作
imag -- 返回complex的實部 (complex、real imag:用于創(chuàng)建和操作復數(shù))
real -- 返回complex的虛部
make -- 用來分配內(nèi)存赐写,返回Type本身(只能應用于slice, map, channel)
new -- 用來分配內(nèi)存鸟蜡,主要用來分配值類型,比如int挺邀、struct揉忘。返回指向Type的指針
cap -- capacity是容量的意思,用于返回某個類型的最大容量(只能用于切片和 map)
copy -- 用于復制和連接slice悠夯,返回復制的數(shù)目
len -- 來求長度癌淮,比如string、array沦补、slice乳蓄、map、channel 夕膀,返回長度
print虚倒、println -- 底層打印函數(shù)美侦,在部署環(huán)境中建議使用 fmt 包
- 內(nèi)置接口error
type error interface { //只要實現(xiàn)了Error()函數(shù),返回值為String的都實現(xiàn)了err接口
Error() String
}
init
函數(shù)
go語言中init
函數(shù)用于包(package)
的初始化魂奥,該函數(shù)是go語言的一個重要特性菠剩。
有下面的特征:
1 init函數(shù)是用于程序執(zhí)行前做包的初始化的函數(shù),比如初始化包里的變量等
2 每個包可以擁有多個init函數(shù)
3 包的每個源文件也可以擁有多個init函數(shù)
4 同一個包中多個init函數(shù)的執(zhí)行順序go語言沒有明確的定義(說明)
5 不同包的init函數(shù)按照包導入的依賴關系決定該初始化函數(shù)的執(zhí)行順序
6 init函數(shù)不能被其他函數(shù)調(diào)用耻煤,而是在main函數(shù)執(zhí)行之前具壮,自動被調(diào)用
main
函數(shù)
Go語言程序的默認入口函數(shù)(主函數(shù)):func main()
函數(shù)體用{}一對括號包裹。
func main(){
//函數(shù)體
}
init
函數(shù)和main
函數(shù)的異同
相同點:
兩個函數(shù)在定義時不能有任何的參數(shù)和返回值哈蝇,且Go程序自動調(diào)用棺妓。
不同點:
init可以應用于任意包中,且可以重復定義多個炮赦。
main函數(shù)只能用于main包中怜跑,且只能定義一個。
兩個函數(shù)的執(zhí)行順序:
對同一個go文件的init()
調(diào)用順序是從上到下的吠勘。
對同一個package
中不同文件是按文件名字符串比較“從小到大”順序調(diào)用各文件中的init()
函數(shù)性芬。
對于不同的package
,如果不相互依賴的話剧防,按照main包中"先import的后調(diào)用"的順序調(diào)用其包中的init()
植锉,如果package
存在依賴,則先調(diào)用最早被依賴的package
中的init()
诵姜,最后調(diào)用main函數(shù)汽煮。
如果init函數(shù)中使用了println()
或者print()
你會發(fā)現(xiàn)在執(zhí)行過程中這兩個不會按照你想象中的順序執(zhí)行搏熄。這兩個函數(shù)官方只推薦在測試環(huán)境中使用棚唆,對于正式環(huán)境不要使用。
歡迎您關注程序員同行者訂閱號心例,程序員同行者是一個技術分享平臺宵凌,主要是運維自動化開發(fā):linux、python止后、django瞎惫、saltstack、redis译株、golang瓜喇、docker、kubernetes歉糜、vue等經(jīng)驗分享及經(jīng)驗交流乘寒。
趁現(xiàn)在,關注我們
牛人并不可怕匪补,可怕的是牛人比我們還努力伞辛!
如果您覺得不錯烂翰,請別忘了轉(zhuǎn)發(fā)、分享蚤氏、點贊讓更多的人去學習甘耿, 您的舉手之勞,就是對小編最好的支持竿滨,非常感謝佳恬!