這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
本文為轉載,原文:Golang 學習筆記(1)—— 基礎
Golang介紹
Go語言是由Google開發的一個開源項目,目的之一為了提高開發人員的開發效率。Go語言文法靈活、簡潔、清晰、高效。它的並發特性可以方便地用於多核處理器和網路開發,同時靈活新穎的類型系統可以方便地編寫模組化的系統。go可以快速編譯,同時具有垃圾記憶體自動回收功能,並且還支援運行時反射。Go是一個高效、靜態類型,但是又具有解釋語言的動態類型特徵的系統級文法。
語言基礎
第一個go程式
我們學習每一門語言都少不了一個hello world
的開始。現在我們就獻上我們的第一個程式
package mainimport "fmt"func main(){ fmt.Println("hello world")}
運行結果如我們所料:
代碼解釋
第一行,package
定義了程式包main
。第二行,引入了fmt
包,func main()
定義了main
函數,func
是定義函數的關鍵字,在main
函數中調用了fmt
包中的Println
方法輸出hello world
字串。
注意
:
- 在go語言中,語句末尾的分號
;
是可以省略的
- 在go語言中,程式碼片段的起始花括弧
{
不能換行,否則程式報錯。
基本類型
類型 |
長度(位元組) |
說明 |
bool |
1 |
true , false 。 不能把非零值當做true |
byte |
1 |
uint8 別名 |
rune |
4 |
int32 別名。代表一個Unicode字元 |
int/uint |
4 |
依據所啟動並執行平台,可能是32bit或64bit。 |
int8/uint8 |
1 |
1-128 ~ 127; 0 ~ 255 |
int16/uint16 |
2 |
-32768 ~ 32767; 0 ~ 65535 |
int32/uint32 |
4 |
-21億 ~ 21億;0 ~ 42億 |
complex64 |
8 |
複數類型,即32位實數+32位虛數 |
complex128 |
16 |
複數類型,即64位實數+64位虛數 |
uintptr |
|
能夠儲存指標的32位或64位整數 |
array |
|
數組,實值型別,如:[2]int |
struct |
|
結構體,實值型別 |
string |
|
實值型別 |
slice |
|
參考型別,如:[]int |
map |
|
參考型別 |
channel |
|
參考型別 |
Interface |
|
介面類型 |
function |
|
函數類型 |
定義變數
package mainimport "fmt"func main(){ var b bool //定義指定類型的變數 var n int //定義指定類型的變數 var i int = 3 //定義指定類型的變數,並賦予預設值 var( //多變數的定義 aa int = 4 str string ) var i1,i2,i3 int = 1,2,3 //多個同類型的變數定義,並賦值 var strName = "bob" //go會自動檢測變數的類型 strSex := "male" //:=定義變數,並給變數賦值,可省略var關鍵字 fmt.Println("n = ", n) fmt.Println("i = ", i) fmt.Println("b = ", b) fmt.Println("aa = ", aa) fmt.Println("str = ", str) fmt.Println("i1 = ", i1, "i2 = ", i2, "i3 = ", i3) fmt.Println("strName = ", strName) fmt.Println("strSex = ", strSex)}
編譯運行:
你會發現,
b=false
,
n=0
,
str=
; 對於未賦值的變數,Go會自動初始化,數實值型別為0,布爾類型為false,字串類型為空白。
注意:
在Go語言中定義了未使用的變數,編譯會報錯;引入未使用的包編譯也會報錯。
常量
常量必須是編譯期能確定的,常量的定義使用const
,常量的類型可以是char
, string
, bool
和數字常量
。因為編譯態的限制,定義他們的運算式必須是常量運算式,可以被編譯器求值。例如,1<<3
是常量運算式,math.Sin(math.Pi/4)
不是, 因為math.Sin
的函數調用發生在運行態。
常量的定義與變數類似,只是關鍵字變成了const
:
const PI = 3.1415926535const msg = "hello"const( z = false a = 123)const x, y = "xxxx", "yyyy"
go語言中沒有枚舉類型,可以用常量類比。可以用iota
產生從0開始的自動成長的枚舉值。按行遞增,可以省略後續行的iota
關鍵字。
const( Sunday = iota //0 Monday //1 TuesDay //2)
也可以在同一行使用多個iota
,他們各自增長
const( U, V = iota, iota //U=0,V=0 W, X //W=1,X=1 Y, Z //Y=2,Z=2)
如果某行不想遞增,可單獨提供初始值。不過想要恢複遞增,必須再次使用iota
const( A1 = iota //0 A2 //1 str = "hello" //hello s //沒有賦值,跟上一行一樣 A3 = iota //恢複遞增,值為4 A4 //5)
流程式控制制
if else
go的if與C和java中的是相似的,區別在於沒有小括弧
func main(){ a := 2 if a==2{ fmt.Println("a=2") }}
在if和條件之間可以包括一些初始運算式,以上代碼可以寫成:
func main(){ if a := 2; a==2{ fmt.Println("a=2") }}
但是請記住,if和條件之間只能有一個初始設定式,否則會編譯報錯。
Switch
go的switch非常靈活,運算式不必是常量或整數,執行的過程從上到下,直到找到匹配項;而如果switch沒有運算式,他會匹配true。
go裡面switch預設相當於每個case最後帶有break
,匹配成功後不會自動向下執行其他case,而是跳出整個switch,但是可以使用fallthrough
強制執行後面的case代碼,fallthrough
相當於去掉了case後面預設的break
。
func main(){ i := 5 switch i{ case 1: fmt.Println("i is equal to 1") case 2: fmt.Println("i is equal to 2") case 3,4,5,6: fmt.Println("i is equal to 3,4,5 or 6") default: fmt.Println("others") }}
結果如下:
如果在最後一個case後面加上
fallthrough
func main(){ i := 5 switch i{ case 1: fmt.Println("i is equal to 1") case 2: fmt.Println("i is equal to 2") case 3,4,5,6: fmt.Println("i is equal to 3,4,5 or 6") fallthrough default: fmt.Println("others") }}
結果如下,依然執行了defaul內的代碼:
不指定switch條件運算式,或直接為true時,可以替代
if...else if...else...
,如:
func main(){ i := 5 switch { case i < 0: fmt.Println("小於零") case i > 0: fmt.Println("大於零") default: fmt.Println("等於零") }}
結果:
for
go只有一個關鍵字用於引入迴圈。但它提供了除do-while
外C語言當中所以可用的迴圈方式。
go的for迴圈有如下三種形式:
for init; condition; post{} //和C的for一樣for condition{} //和while一樣for{} //死迴圈
如:
func main(){ str := "Chain" for i, j := 0, len(str); i < j; i++{ fmt.Println(string(str[i])) }}
運行結果:
使用
break
可以提前終止當前迴圈,嵌套迴圈時,可以在
break
後面指定能夠標籤,用來終止指定的迴圈,如:
func main(){ oute: for i := 0; i < 5; i ++{ for j := 0; j < 3; j++{ if(i > 2){ break oute } fmt.Println("i=",i,"j=", j) } }}
結果:
continue
用於終止本次迴圈體的執行,繼續下一個迴圈,與
breck
相同,對於嵌套迴圈,可以用標籤來指定要繼續哪一層迴圈。