你好,Go
Go語言是一門類似C語言的編譯型語言,它的編譯速度非常快。這門語言的關鍵字一共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
本章中,筆者將帶領你去學習Go語言的基礎。通過每一小節的介紹,你將發現,Go語言的世界是多麼簡潔,設計是如此美妙,編寫Go語言將會是一件愉快的事情。等回過頭來,你就會發現這25個關鍵字是多麼親切。
在開始編寫應用之前,我們先從最基本的程式開始。就像你造房子之前不知道什麼是地基一樣,編寫程式也不知道如何開始。因此,在本節中,我們要學慣用最基本的文法讓Go語言程式運行起來。
程式
這就像一個傳統,在學習大部分語言之前,你先學會如何編寫一個可以輸出Hello World的程式。
準備好了嗎?讓我們開始吧!
package main
import "fmt"
func main() {
fmt.Printf("Hello, world or 你好,世界 or καλημ ́ρα κóσμor こんにちは世界\n")
}
輸出如下。
Hello, world or 你好,世界 or καλημ ́ρα κóσμor こんにちは世界
詳解
首先我們要瞭解一個概念,Go語言程式是通過package來組織的。
package <pkgName>(在我們的例子中是package main)這一行告訴我們當前檔案屬於哪個包,而包名main則告訴我們它是一個可獨立啟動並執行包,它在編譯後會產生可執行檔。除了main包之外,其他的包最後都會產生*.a檔案(也就是包檔案),並放置在$GOPATH/pkg/$GOOS_$GOARCH中(以Mac為例就是$GOPATH/pkg/darwin_amd64)。
每一個可獨立啟動並執行Go語言程式,必定包含一個package main,在這個main包中必定包含一個入口函數main,而這個函數既沒有參數,也沒有傳回值。
為了列印Hello, World...,我們調用了一個函數Printf,這個函數來自於fmt包,所以我們在第三行中匯入了系統層級的fmt包:import"fmt"。
包的概念和Python中的module相同,它們都有一些特別的好處:模組化(能夠把程式分成多個模組)和可重用性(每個模組都能被其他應用程式反覆使用)。我們在這裡只是先瞭解一下包的概念,後面我們將會編寫自己的包。
在第五行,我們通過關鍵字func定義了一個main函數,函數體被放在{}中,就像我們平時寫C、C++或Java時一樣。大家可以看到main函數是沒有任何參數的,我們接下來就學習如何編寫帶參數的、返回0個或多個值的函數。
第六行,我們調用了fmt包裡面定義的函數Printf。大家可以看到,這個函數通過<pkgName>.<funcName>的方式調用,這一點和Python十分相似。
前面提到過,包名和包所在的檔案夾名可以是不同的,此處的<pkgName>即為通過package<pkgName>聲明的包名,而非檔案夾名。
最後大家可以看到我們輸出的內容裡麵包含了很多非ASCII碼字元。實際上,Go語言是天生支援UTF-8的,任何字元都可以直接輸出,你甚至可以用UTF-8中的任何字元作為標識符。
小結
Go語言使用package(和Python的模組類似)來組織代碼。main.main()函數(這個函數主要位於主包)是每一個獨立的可運行程式的進入點。Go語言使用UTF-8字串和標識符(因為UTF-8的發明者也就是Go語言的發明者),所以它天生就具有多語言的支援。
Go語言基礎
定義變數
Go語言裡面定義變數有多種方式。
使用var關鍵字是Go語言最基本的定義變數方式,與C語言不同的是Go語言把變數類型放在變數名後面,如下所示。
//定義一個名稱為“variableName”,類型為"type"的變數
var variableName type
定義多個變數。
//定義三個類型都是“type”的三個變數
var vname1, vname2,vname3 type
定義變數並初始化值。
//初始化“variableName”的變數為“value”值,類型是“type”
var variableName type= value
同時初始化多個變數。
/*
定義三個類型都是"type"的三個變數,並且它們分別初始化相應的值
vname1為v1,vname2為v2,vname3為v3
*/
var vname1, vname2, vname3 type= v1, v2, v3
你是不是覺得上面這樣的定義有點繁瑣?沒關係,因為Go語言的設計者也發現了,有一種寫法可以讓它變得簡單一點。我們可以直接忽略型別宣告,那麼上面的代碼變成如下所示。
/*
定義三個變數,它們分別初始化相應的值
vname1為v1,vname2為v2,vname3為v3
然後Go會根據其相應值的類型來幫你初始化它們
*/
var vname1, vname2, vname3 = v1, v2, v3
你覺得上面的還是有些繁瑣?好吧,讓我們繼續簡化。
/*
定義三個變數,它們分別初始化相應的值
vname1為v1,vname2為v2,vname3為v3
編譯器會根據初始化的值自動推匯出相應的類型
*/
vname1, vname2, vname3 := v1, v2, v3
現在是不是看上去非常簡潔了“?:=”這個符號直接取代了var和type,這種形式叫做簡短聲明。不過它有一個限制,那就是它只能用在函數內部;在函數外部使用則會無法編譯通過,所以一般用var方式來定義全域變數。
_(下畫線)是個特殊的變數名,任何賦予它的值都會被丟棄。在這個例子中,我們將值35賦予b,並同時丟棄34。
_, b := 34, 35
Go語言對於已聲明但未使用的變數會在編譯階段報錯,比如下面的代碼就會產生一個錯誤:聲明了i但未使用。
package main
func main() {
var i int
}
常量
所謂常量,也就是在程式編譯階段就確定下來的值,而程式在運行時則無法改變該值。在Go語言程式中,常量可定義為數值、布爾值或字串等類型。
它的文法如下。
const constantName =value
//如果需要,也可以明確指定常量的類型:
const Pi float32 =3.1415926
以下是一些常量聲明的例子。
const Pi = 3.1415926
const i = 10000
const MaxThread = 10
const prefix = "astaxie_"
本文節選自《Go Web編程》一書
謝孟軍 著
電子工業出版社出版