簡介
目前正在學Go,做下記錄,溫故而知新,初學coding的時候可以快速翻查用法,瞭解原理。
多重賦值
多重賦值時,變量的左值和右值按從左到右的順序賦值
var a int = 100
b := 200
b,a = a,b // 實現交換
匿名變量
匿名變量 '_'表示,使用匿名變量時,只需要在變量聲明的地方使用下劃線替換即可。
a,_ = Get_data()
匿名變量不佔用空間,不會分配內存。匿名變量與匿名變量之間不會因爲多次聲明而無法使用。
數據類型
整形(int8,int16,int32,int64)、浮點型、布爾型、字符串、數組、切片、結構體、函數(go語言的一種數據類型,可對函數類型的變量進行賦值和獲取)、map、通道(channel)
數組
var variable_name [SIZE] variable_type
數組是一串固定長度的連續內存區域。
數組可以在聲明時使用初始化列表進行元素設置:
var team = [3]string{"hammer","soldier","mum"}
根據元素個數確定數組大小
var team = [...]string{"hammer","soldier","mum"} // ...表示讓編譯器確定數組大小
遍歷數組
for k,v := range team{
fmt.Println(k,v)
}
切片
https://www.cnblogs.com/followyou/p/12349883.html
map
https://www.cnblogs.com/followyou/p/12355313.html
函數
https://www.cnblogs.com/followyou/p/12348259.html
結構體
https://www.cnblogs.com/followyou/p/12358919.html
接口(interface)
https://www.cnblogs.com/followyou/p/12601846.html
指針
go拆分兩個核心概念
- 類型指針 允許對這個指針類型的數據進行修改。傳遞數據使用指針,而無需拷貝數據。類型指針不能進行偏移和運算
- 切片 由指向起始元素的原始指針、元素數量和容量組成
go的指針類型變量擁有指針的高效訪問,但又不會發生指針偏移,從而避免非法修改關鍵性數據問題。同時,垃圾回收也比較容易對不會發生偏移的指針進行檢索和回收。
切片比原始指針具備更強大的特性,更爲安全。切片發生越界時,運行時會報出宕機,並打出堆棧,而原始指針只會崩潰。
指針地址和指針類型
ptr := &v //v的類型爲T &v取地址 &取地址操作符
//v代表被取地址的變量,被取地址的v使用ptr變量進行接收,ptr的類型爲*T,稱作T的指針類型。
// * 代表指針
變量、指針和地址關係:每個變量都擁有地址,指針的值就是地址
從指針獲取指針指向的值
& 獲取這個變量的指針
- 指針取值
&取出地址,*根據地址取出地址指向的值
變量、指針地址、指針變量、取地址、取值關係:
- 對變量進行取地址(&)操作,可以獲得這個變量的指針變量
- 指針變量的值是指針地址
- 對指針變量進行取值(*)操作,可以獲得指針變量指向的原變量的值
*操作符根本意義就是操作指針指向的變量。當操作在右值時,就是取指向變量的值;當操作在左值時,就是將值設置給指向的變量
類型轉換
T(表達式)
T代表要轉換的類型。、
var a int32 = 1047483647
b:=int16(a)
堆棧知識
- 棧區(stack) --存儲參數值、局部變量,維護函數調用關係等。
- 堆區(heap) --動態內存區域,隨時申請和釋放,程序自身要對內存泄漏負責
- 全局區(靜態區) --存儲全局和靜態變量
- 字面量區 --常量字符串存儲區
- 程序代碼區 --存儲二進制代碼
int a=o; //全局變量
char *p1; //全局未初始化區
main() {
static int b=0; //全局初始化區
int c; //棧
char d[] = "abc:; //棧
char *p2; //棧
char *p3 = "hello"; //hello在常量區,p3在棧上
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); //分配得來的10和20字節的區域就在堆區
strcpy(p1,"hello"); //hello放在常量區,編譯器可能會將它與p3所指向的hello優化成一個地方
}
總體來講,棧上的變量是局部的,隨着局部空間的銷燬而銷燬,由系統負責。
堆上的變量可以提供全局訪問,需要自行處理其聲明週期。
關鍵字
defer
defer用於資源的釋放,會在函數返回之前進行調用
var a,b := 1,2
c := func(a,b int) (c int){
c = a+b
defer func() {
c = c*2
}()
return
}
//6
流程判斷
- 條件判斷 if
- 條件循環 for
- 健值循環 for range
- 分支選擇 switch
switch 默認情況下 case 最後自帶 break 語句,匹配成功後就不會執行其他 case,如果我們需要執行後面的 case,可以使用 fallthrough
switch var1 {
case val1:
fallthrough
case val2:
...
default:
...
}
- 跳轉 goto
- 跳出循環 break 和 繼續循環 continue
健值循環(for range)
可以使用for range遍歷數組、切片、字符串、map、及chnnel。
通過for range遍歷返回值規律:
- 數組、切片和字符串返回索引和值;
- map返回健和值
- chnnel只返回通道內的值
遍歷切片、數組
for key, value := range []int{1, 2, 3, 4} {
fmt.Printf("key%d, value %d\n",key ,value)
}
遍歷獲得字符
str := "hello"
for key, value := range str {
fmt.Printf("key%d, value 0x%x \n",key ,value) //%x 十六進制,小寫字母,每字節兩個字符
}
遍歷map
m := map[string]int{
"a" : 1,
"b" : 2,
}
for key, value := range m {
fmt.Println(key,value)
}
遍歷channel --從通道接收數據
c := make(chan int)
go func(){
//往通道內推送數據,然後結束並關閉通道
c <- 1
c <- 2
c <- 3
close(c)
}()
for value :=range c {
...
}