Go知識記錄

簡介

目前正在學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 {
		...
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章