標籤:select try 條件 接收 代碼 var switch語句 float case
最近新的工作一些代碼是go語言寫的,學了一些go語言的基本文法。後期有一些別的學習總結,在此文檔更新。
1文法1.1變數/常量定義
var v Type
var v Type = value
var v = value
var v1,v2,v3 Type
var v1,v2,v3 Type = value1,value2,value3
var v1,v2,v3= value1,value2,value3
v1,v2,v3:= value1,value2,value3
i,j = j,i
:=為簡短聲明,編譯器根據初始化的值自動推斷相應的類型,但是不能定義在函數外部使用。
const(
s = “string”
pi = 3.1415
pi2
)
var(
i int
pi float32 = 3.1415
)
1.2 array & slice
array定義
var a [2]int = [2]int{1,2}
a := [2]int{1,2}
a := [...]int{1,2,3,4}
a2 := [2][3]int{[3]int{1,2,3},[3]int{3,2,1}}
a2 := [2][3]int{{1,2,3},{3,2,1}}
slice定義
slice是參考型別
var s []int = make([]int,n)
s := []int{v1,v2,v3}
1.3 map
var m map[keyType]valueType //keyType可以是string及完全定義了==/!=操作的類型
m := make(map[keyType]valueType)
m:=map[keyType]valueType{k1:v1,k2:v2,k3:v3}
len(m map[keyType]valueType)int
delete(m map[Type]Type1,key Type)
1.4 if語句
a)條件陳述式不需要使用括弧將條件括起來;
b)無論語句體有幾條語句,花括弧{}都是必須存在的;
c)左花括弧{ 必須與if或者else在同一行;
d)在if之後,條件陳述式之前,可以添加變數初始化語句,用;間隔;
e)在有傳回值的函數中,不允許將“最終的”return語句包含在if...else...中,否則會編譯錯誤。
1.5 go語句
go fmt.Println("Go!") go語句僅由一個關鍵字go和一條運算式語句構成。
go語句的執行與其攜帶的運算式語句的執行在時間上沒有必然聯絡。這裡能夠確定的僅僅是後者會在前者完成之後發生。在go語句被執行時,其攜帶的函數(也被稱為go函數)以及要傳給它的若干參數(如果有的話)會被封裝成一個實體(即Goroutine),並被放入到相應的待運行隊列中。Go語言的運行時系統會適時的從隊列中取出待啟動並執行Goroutine並執行相應的函數叫用作業。注意,對傳遞給這裡的函數的那些參數的求值會在go語句被執行時進行。這一點也是與defer語句類似的。
一句話就是go 語句就是起一個線程。
1.6 select 語句
select是Go中的一個控制結構,類似於用於通訊的switch語句。每個case必須是一個通訊操作,要麼是發送要麼是接收。select隨機執行一個可啟動並執行case。如果沒有case可運行,它將阻塞,直到有case可運行。一個預設的子句應該總是可啟動並執行。
以下描述了 select 語句的文法:
(1)每個case都必須是一個通訊
(2)所有channel運算式都會被求值
(3)所有被發送的運算式都會被求值
(4)如果任意某個通訊可以進行,它就執行;其他被忽略。
(5)如果有多個case都可以運行,Select會隨機公平地選出一個執行。其他不會執行。
否則:
如果有default子句,則執行該語句。
如果沒有default字句,select將阻塞,直到某個通訊可以運行;Go不會重新對channel 或值進行求值。
1.7 nil解釋
(1)nil並不是Go的關鍵字之一,nil的意思是無,或者是零值。在Go語言中,如果你聲明了一個變數但是沒有對它進行賦值操作,那麼這個變數就會有一個類型的預設零值。這是每種類型對應的零值:
bool -> false
numbers -> 0
string -> ""
pointers -> nil
slices -> nil
maps -> nil
channels -> nil
functions -> nil
interfaces -> nil
(2)對於指標對象的方法來說,就算指標的值為nil也是可以調用的;
(3)一個為nil的slice,除了不能索引外,其他的操作都是可以的,當你需要填儲值的時候可以使用append函數,slice會自動進行擴充。
// nil slices
var s []slice
len(s) // 0
cap(s) // 0
for range s // iterates zero times
s[i] // panic: index out of range
(4)對於nil的map,我們可以簡單把它看成是一個唯讀map,不能進行寫操作,否則就會panic。
// nil maps
var m map[t]u
len(m) // 0
for range m // iterates zero times
v, ok := m[i] // zero(u), false
m[i] = x // panic: assignment to entry in nil map
(5)關閉一個nil的channel會導致程式panic。+
(6)interface並不是一個指標,它的底層實現由兩部分組成,一個是類型,一個值,也就是類似於:(Type, Value)。只有當類型和值都是nil的時候,才等於nil。
1.8 管道(Channel)
管道是Go語言在語言層級上提供的goroutine間的通訊方式,我們可以使用channel在多個goroutine之間傳遞訊息。channel是進程內的通訊方式,是不支援跨進程通訊的,如果需要進程間通訊的話,可以使用Socket等網路方式。
管道是類型相關的,即一個管道只能傳遞一種類型的值。管道中的資料是先進先出的。
文法:
1 // 聲明方式,在此ElemType是指此管道所傳遞的類型
2 var chanName chan ElemType
3 // 聲明一個傳遞類型為int的管道
4 var ch chan int
5 // 聲明一個map,元素是bool型的channel
6 var m map[string] chan bool
7
8 // 定義文法,定義需要使用內建函數make()即可,下面這行代碼是聲明+定義一個整型管道
9 ch := make(chan int)
10 // 事先定義好管道的size,下面這行代碼定義管道的size為100
11 ch := make(chan int, 100)
12
13 // 由管道中讀寫資料,<-操作符是與最左邊的chan優先結合的
14 // 向管道中寫入一個資料,在此需要注意:向管道中寫入資料通常會導致程式阻塞,直到有
15 // 其他goroutine從這個管道中讀取資料
16 ch<- value
17 // 讀取資料,注意:如果管道中沒有資料,那麼從管道中讀取資料會導致程式阻塞,直到有資料
18 value := <-ch
19
20 // 單向管道
21 var ch1 chan<- float64 // 只能向裡面寫入float64的資料,不能讀取
22 var ch2 <-chan int // 只能讀取int型資料
23
24 // 關閉channel,直接調用close()即可
25 close(ch)
26 // 判斷ch是否關閉,判斷ok的值,如果是false,則說明已經關閉(關閉的話讀取是不會阻塞的)
27 x, ok := <-ch
用法例子:
1 package main
2 import "fmt"
3
4 func print(ch chan int) {
5 fmt.Println("Hello world")
6 ch<- 1
7 }
8
9 func main() {
10 chs := make([]chan int)
11 for i := 0; i < 10; i++ {
12 chs[i] = make(chan int)
13 go print(chs[i])
14 }
15
16 for _, ch := range(chs){
17 <-ch
18 }
19 }
go語言學習小結