--------------------------------------------------------------------------
優(yōu)勢(shì):
1.它是系統(tǒng)級(jí)別的語言,靜態(tài)編譯,是C系列語言。
2.具有很多內(nèi)置庫,使用起來和Python很類似。
3.語法足夠簡單,入門學(xué)習(xí)成本很低,適合我這樣從PHP和Python切換過來的人。
4.速度快,就拿簡單的頁面來說,我用PHP開發(fā)并發(fā)能夠達(dá)到500很好了,但是用Go輕松就到上萬,這是無法比擬的性能
提升,而且用Go開發(fā)的效率和PHP差不多。
5.出自Google之手,而且有一幫牛人在維護(hù),基于BSD開源,社區(qū)活躍。
--------------------------------------------------------------------------
缺點(diǎn):
1.有些庫不成熟,例如圖像處理。
2.cgo在Window系統(tǒng)下面編譯很麻煩,就拿SQLite的數(shù)據(jù)庫驅(qū)動(dòng)來說,在Window下面編譯就會(huì)遇到很大的麻煩。
3.runtime還不夠成熟,GC還不是很好,不過聽說Go 1.1版本會(huì)有比較大的性能提升。
4.Go的開源項(xiàng)目還不夠多。我覺得一個(gè)語言的發(fā)展不僅僅是語言本身出色,還要有大公司推動(dòng)或者好的項(xiàng)目推動(dòng)。
--------------------------------------------------------------------------
開源項(xiàng)目
開源項(xiàng)目給我很多自信,舉幾個(gè)開源系統(tǒng):
vitess(YouTube的數(shù)據(jù)庫proxy系統(tǒng))、
nsq(bitly的一個(gè)實(shí)時(shí)信息處理系統(tǒng))、
skynet(輕量級(jí)的分布式服務(wù)框架)、
七牛公司全部用Go開發(fā)、
360開發(fā)的類iMessage應(yīng)用,支持上千萬用戶,同時(shí)單臺(tái)服務(wù)器長連80w,
這些系統(tǒng)都是他們線上跑的,這給我更大的信心能夠用Go來開發(fā)高性能,高穩(wěn)定的應(yīng)用。
--------------------------------------------------------------------------
為什么Go被稱為互聯(lián)網(wǎng)時(shí)代的C呢
我認(rèn)為是Go在語言級(jí)別上支持了并發(fā),通過簡單的關(guān)鍵字go就可以充分利用多核,這對(duì)于硬件不斷發(fā)展的時(shí)代,這么簡
單就可以充分利用硬件的多核,這是多么重要的一個(gè)特性啊!但是相比C而言,Go還缺少一些高質(zhì)量的第三方包,例如
OpenGL等,所以Go內(nèi)部也支持用cgo直接調(diào)用C語言編寫的代碼。
同時(shí)我還開發(fā)了兩個(gè)開源的項(xiàng)目:
beego:一個(gè)模仿Python的tornado系統(tǒng)開發(fā)的Go開發(fā)框架,現(xiàn)在開發(fā)的幾個(gè)系統(tǒng)都是基于該框架開發(fā)。
beedb: 一個(gè)Go語言的ORM庫,可以像操作struct一樣操作數(shù)據(jù)庫數(shù)據(jù)。目前我們內(nèi)部的API接口我就是采用了這個(gè)ORM
開發(fā)的。
1.書籍《go語言程序設(shè)計(jì)》
1.1 go語言是一門靜態(tài)編譯型的語言。編譯速度非常快,明顯快于c,c++。
go語言的官方編譯器是gc。
查看官方文檔: 運(yùn)行指令 godoc -http=:8000 在瀏覽器中打開http://localhost:8000就可以查看go語言官方文
檔。
go語言支持在程序中以cgo工具的形式調(diào)用外部的c語言代碼。
1.2 編輯
go語言關(guān)鍵字和操作符都使用ASCII編碼字符,但是GO語言中的標(biāo)識(shí)符可以使任一Unicode編碼字符串,所以go語言
開發(fā)者可以再代碼中自由地使用它們的母語。
編譯
go語言的編譯速度超快,所以go語言可以作為類UNIX系統(tǒng)上的#!腳本使用。將#!/usr/bin/env gonow 或者
#!/usr/bin/env gorun加到main()所在的.go文件開始處即可
。
示例
www.qtrac.eu/gobook.html 得到本書所有的源碼。
環(huán)境變量設(shè)置
在.bashrc文件中添加以下行:
export GOROOT=$HOME/opt/go
export PAHT=$PATH:$GOROOT/bin
http://www.qtrac.eu/gobook-1.0.zip
gofmt -w src 可以格式化整個(gè)項(xiàng)目
如何查看相應(yīng)的package文檔?
如果是 builtin包,那么執(zhí)行g(shù)odoc builtin
如果是 http 包, 那么執(zhí)行g(shù)odoc net/http
如果查看某一個(gè)包里面的函數(shù),則執(zhí)行g(shù)odoc fmt Printf,也可以查看相應(yīng)的代碼,執(zhí)行 godoc -src fmt Printf
-----------------------------------
UTF-8 天生支持utf-8字符串和標(biāo)示符,因?yàn)閡tf-8的發(fā)明者也是go語言的發(fā)明者。
并發(fā)
goroutine 是go語言并行設(shè)計(jì)的核心,goroutine說到底就是線程,但是它比線程更小,十幾個(gè)goroutine可能
體現(xiàn)在底層就是五六個(gè)線程,go語言內(nèi)部幫你實(shí)現(xiàn)了這些goroutine之間的內(nèi)存共享。
執(zhí)行g(shù)oroutine只需極小的棧內(nèi)存(4--5k)。
默認(rèn)情況下,調(diào)度器僅使用單線程。想要發(fā)揮多核處理器的并行,需要在我們的程序中顯示調(diào)用
runtime.GOMAXPROCS(n) 告知調(diào)度器同時(shí)使用多個(gè)線程。
channel
1.無緩沖的 channel
默認(rèn)情況下,channel接收和發(fā)送數(shù)據(jù)都是阻塞的,除非另一端已經(jīng)準(zhǔn)備好,這樣就使得goroutine同步變得更加簡
單,而不需要顯式的lock。
所謂阻塞,也就說如果讀取,它就會(huì)被阻塞,直到有數(shù)據(jù)接收;任何發(fā)送也會(huì)被阻塞,直到讀數(shù)據(jù)被讀出。
無緩沖的channel是在多個(gè)goroutine之間同步最棒的工具。
2.有緩沖的channel
ch := make(chan bool ,4)創(chuàng)建了一個(gè)可以存儲(chǔ)4個(gè)元素的bool型channel 。在這個(gè)channel中,前4個(gè)元素可以無
阻塞的寫入。當(dāng)寫入第5個(gè)元素時(shí),代碼將會(huì)阻塞,直到其他goroutine從channel中讀取一些元素,騰出空間。
range 和close
func Test(){
c := make(chan int, 10)
go fibonacci(cap(c) ,c)
for i := range c { //使用range操作緩存類型的channel
fmt.Println(i)
}
}
func fibonacci(n int,c chan int){
x,y := 1,1
for i := 0 ;i < n ;i++ {
c <- x
x,y = y,x+y
}
close(c) //在生產(chǎn)者的地方關(guān)閉channel,而不是在消費(fèi)的地方去關(guān)閉它,這樣容易起panic。
}
select
func Test(){
c := make(chan int)
quit := make(chan int)
go func(){
for i :=0 ;i<10;i++{
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c,quit)
}
func fibonacci(c,quit chan int){
x,y := 1,1
for {
select {//*select 默認(rèn)是阻塞的,只要當(dāng)監(jiān)聽的channel中發(fā)送或者接收可以進(jìn)行時(shí),才會(huì)運(yùn)行。
case c <-x ://*當(dāng)多個(gè)channel都準(zhǔn)備好的時(shí)候,select是隨機(jī)選擇一個(gè)執(zhí)行的。
x,y = y,x+y
case <-quit:
fmt.Println("quit")
return
default:
fmt.Println("do some thing ");
}
}
}
超時(shí)
func Test(){
c := make(chan int)
o := make(chan bool)
go func(){
for {
select {
case v := <-c :
fmt.Println(v)
case <- time.After(5 * time.Second) :
fmt.Println("timeout")
o <- true
break
}
}
}()
<- o
}