這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近看了看GoLang,把Go語言的文法總結了一下,做個快速參考
資料類型
var varName type
,var var1,var2… type
,var varName type = Value
,var varName1,varName2 type = Value1,Value2
,var varName1,varName2=Value1,Value2
,varName1,varName2:=Value1,Value2
,定義資料類型。
聲明了沒有被使用的變數將在編譯時間報錯。
常量定義: const varName = Value
, const varName type = Value
string
字串類型值不可改變,但是可以切片,字串可以使用+
進行串連
iota
用來聲明enum
,表示自加1,初始為0
var arrayName [N]type
用來聲明數組,或者使用 arrayName := [N]type{ v1,v2…}
來聲明
數組聲明可以嵌套
slice
用來表示切片,聲明方式var sliceName []type
或者sliceName := []type{v1,v2…}
slice
儲存的是引用而非實體
在slice
中有一些內建函數,len
擷取長度,cap
擷取最大容量,append
追加資料,copy
用來拷貝資料
map
聲明方式為var mapName map[keyType] valueType
或者mapName := make(map[keyType]valueType)
map
可通過 key : value
初始化
make
用於內建類型的記憶體配置,new
用於各種類型的記憶體配置,new
返回指標而make
返回非0的值
流程式控制制
if
語句不需要括弧,在if語句中可以聲明變數,用分好分割if
語句的條件判斷
if x:=function();x<10 { fmt.Printf("x < 10,%d\n",x); }else{ fmt.Print("x >= 10 ,%d\n",x); }
goto
語句類似C語言,但是跳轉到必須在當前函數內定義的標籤
for
語句類似C語言,但是break
和continue
可以跟標號,跳出多重迴圈。
switch
語句不用break
,如果想強行執行下面的case可以使用fallthrough
函數
聲明方式:
func funcName(input1 type1, input2 type2) (output1 type1, output2 type2)
func
用來聲明函數,函數名為funcName
,後面跟輸入,輸出的資料類型。
函數可以有多個傳回值
函數的值操作和指標操作類似C語言,內建類型中的string
,slice
,map
直接使用的是類似的指標傳遞,不用使用取地址符,但是,如果需要改變slice
的長度,則需要取地址穿指標。
defer
語句用來表示在函數返回前執行的語句。
type typeName func(input1 inputType1 , input2 inputType2 [, ...]) (result1 resultType1 [, ...])
用來聲明一個函數類型,主要用於高階函數中。
import
用來匯入包,package
用來匯出包,包操作使用.
操作符
Struct類型
聲明方式:
type Person struct { name string age int }
匿名方式,匿名方式下A含有B的所有類型
type Student struct { Person // 預設Person的所有欄位 speciality string }
如果匿名型別中有欄位和本身有衝突,可以使用匿名型別+.
訪問
類型的方法聲明:
func (r ReceiverType) funcName(parameters) (results)
可以使用:type typeName typeLiteral
來自訂類型,定義完以後可以使用方法來擴充類型的功能。
需要改變struct內部的值時,需要將ReceiverType
定義為*
指標類型,但是調用的時候不需要,go語言自動幫你完成了。
方法可以繼承,可以重載
interface介面
type InterfaceName interface
用來定義inerface
interface類型定義了一組方法,如果某個對象實現了某個介面的所有方法,則此對象就實現了此介面。
空interface(interface{})不包含任何的method,正因為如此,所有的類型都實現了空interface
一個函數把interface{}作為參數,那麼他可以接受任意類型的值作為參數,如果一個函數返回interface{},那麼也就可以返回任意類型的值
value, ok = element.(T)
,這裡value
就是變數的值,ok
是一個bool
類型,element
是interface
變數,T是斷言的類型,如果ok
為true
則表示,element
確實是T
類型的。
interface
可以嵌套
並發
使用go
關鍵字+函數名
實現並發
使用channel
實現線程間通訊,channel
通過make
構造,使用<-
來發送和接受資料。
chan
是channel
的關鍵字,後面跟資料類型ch <- v
發送資料,v:=<-ch
接收資料,ch
是chan
類型。
package main import "fmt" func sum(a []int, c chan int) { total := 0 for _, v := range a { total += v } c <- total // send total to c } func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[:len(a)/2], c) go sum(a[len(a)/2:], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x + y) }
channel
預設是阻塞形式的,可以進行線程同步。
ch := make(chan type, value)
構造channel時可通過設定不同的value
來設定channl的buffer長度。
close
用來關閉channel
使用select
+case
來選擇多個channel
使用select
+ case <- time.After(5 * time.Second)
來設定逾時
Goexit
退出當前執行的goroutine,但是defer函數還會繼續調用
Gosched
讓出當前goroutine的執行許可權,調度器安排其他等待的任務運行,並在下次某個時候從該位置恢複執行。
NumCPU
返回 CPU 核心數量
NumGoroutine
返回正在執⾏行和排隊的任務總數
GOMAXPROCS
用來設定可以啟動並執行CPU核心數