Go語言擁有兩大數據類型,基本數據類型和復合數據類型。
1. 數值類型
##有符號整數
int8(-128 -> 127)
int16(-32768 -> 32767)
int32(-2,147,483,648 -> 2,147,483,647)
int64(-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807)
int( 32 位操作系統上32 位,64 位操作系統64 位)##無符號整數
uint8(0 -> 255)
uint16(0 -> 65,535)
uint32(0 -> 4,294,967,295)
uint64(0 -> 18,446,744,073,709,551,615)
uint ( 32 位操作系統上32 位,64 位操作系統64 位)##浮點型
float32(+- 1e-45 -> +- 3.4 * 1e38)
float64(+- 5 1e-324 -> 107 1e308)
#無float類型#復數
Go 擁有以下復數類型:
complex64 (32 位實數和虛數)
complex128 (64 位實數和虛數)復數使用 re+imI 來表示,其中 re 代表實數部分, im 代表虛數部分,I 代表根號負 1
var c1 complex64 = 5 + 10i
fmt.Printf("The value is: %v", c1) // 輸出: 5 + 10i
1.1 整型
int后面的數字代表位數,而前面的u代表無符號。Go語言中int類型的大小與具體的平臺有關系,一般來說,int在32位系統中是4字節,在64位系統中是8字節,使用簡短定義自動推導類型初始化一個整數,默認為int類型。
1.2 浮點型
Go語言有兩種精度的浮點數 float32 和 float64,分別占4個字節和8個字節
1.3 數值類型使用注意
-
整型的零值為 0,浮點型的零值為 0.0。
-
int 和 uint 在 32 位操作系統上,它們均使用 32 位(4 個字節) ,在 64 位操作系統上,它們均使用 64 位(8 個字節)。
-
uintptr 的長度被設定為足夠存放一個指針即可。
-
整型的零值為 0,浮點型的零值為 0.0。
-
int 型是計算最快的一種類型。
-
盡可能地使用 float64,因為 math 包中所有有關數學運算的函數都會要求接收這個類型。
-
Go 是強類型語言,不會進行隱式轉換.。所以Go 中不允許不同類型之間的混合使用,但允許常量之間的混合使用。
2.字符串
字符串由“ ”聲明,由多個字節組成,需要使用"進行轉義后才能使用 \n \r \t 為特殊作用字符。
- 字符串是 UTF-8 字符的一個序列(當字符為 ASCII 碼時則占用 1 個字節,其它字符根據需要占用 2-4 個字節)
- 字符串在Go語言內存模型中用一個2字長的數據結構表示。它包含一個指向字符串存儲數據的指針和一個長度數據。
- 字符串是一種值類型,且值不可變。所以多字符串共享同一個存儲數據是安全的。
- 切分操作 str[i:j] 會得到一個新的2字長結構,一個可能不同的但仍指向同一個字節序列(即上文說的存儲數據)的指針和長度數據。字符串切分不涉及內存分配。
- string 類型的零值為ptr為nil,len為0的字符串,即空字符串 “”
- 獲取字符串中某個字節的地址的行為是非法的,例如: &str[i]
3. 布爾
兩種取值類型,true false
- 對于布爾值的好的命名能夠很好地提升代碼的可讀性,例如以 is 或者 Is 開頭的isSorted 、 isFinished 、 isVisivle 。
- 在格式化輸出時,你可以使用 %t 來表示你要輸出的值為布爾型。
- 布爾型的值只可以是常量 true 或者 false。
4. 數據類型的轉換
強制類型轉換的語法 Type(value)。Type 為目標數據類型
5. 運算符
算術運算符,邏輯運算符,關系運算符,賦值運算符與Java,c++相差無幾,就不多贅述了
位運算存在一些差別
6. 占位符號
占位符表示在程序中輸出一行字符串時候,或者格式化輸出字符串的時候使用。go內置包fmt中Printf方法可以在控制臺格式化打印出用戶輸入的內容。fmt.Printf("%T",x)
T代表type類型,s代表字符串string,t代表布爾值,d代表十進制數字,p代表內存地址
7. 數組
數組聲明的語法格式為: var 數組名稱 [長度]數據類型
- 數組的長度,用內置函數 len()來獲取。
- 數組的容量,用內置函數 cap()來獲取。
//默認情況下 數組中每個元素初始化時候 根據元素的類型 對應該數據類型的零值,
arr1 := [3]int{1,2}
fmt.Println(arr1[2])//下標為2的元素沒有默認取int類型的零值//數組創建方式1 創建時 直接將值賦到數組里
arr2 := [5]int{1,2,3,4} //值可以少 默認是0 但是不能超過定長//在指定位置上存儲值
arr3 := [5]int{1:2,3:5}//在下標為1的位置存儲2,在下標為3的位置存儲5
//長度可以用...代替 根據數值長度程序自動填充數值的大小
arr4 := [...]int{1,2,3,4}//簡短聲明方式
arr5 := [...]int{2:3,6:3}//在固定位置存儲固定的值arr := [5]int{1,2,3,4,5}
//range方式循環數組
for index,value:=range arr{fmt.Println(index,value)
}//聲明一個二維數組
var arr [3][8]int
//給二維數組賦值
arr[0]=[8]int{1,2,3,4,5,6,7,8}
//打印結果
fmt.Println(arr) // [[1 2 3 4 5 6 7 8] [0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0]]
//也可以通過下標給指定的索引賦值
arr[1][3]=9
fmt.Println(arr) // [[1 2 3 4 5 6 7 8] [0 0 0 9 0 0 0 0] [0 0 0 0 0 0 0 0]]
8. 切片Slice
聲明一個切片語法:var 切片名字 [] 數據類型
通常情況下,使用make函數來創建一個切片,切片有長度和容量,默認情況下它的容量與長度相等。所以可以不用指定容量。
//使用make函數來創建切片
slice :=make([]int,3,5)//長度為3 容量為5 容量如果省略 則默認與長度相等也為3
fmt.Println(slice)//[0,0,0]
fmt.Println(len(slice),cap(slice))//長度3,容量5
- 一個slice是一個數組某個部分的引用。在內存中,它是一個包含3個域的結構體:指向slice中第一個元素的指針,slice的長度,以及slice的容量。
- 切片 s 來說該不等式永遠成立: 0 <= len(s)<= cap(s)
- 在對slice進行append等操作時,可能會造成slice的自動擴容(因為切片的底層是一個數組,數組的容量是不可變的,因此每次擴容都要產生一個新數組):
- 首先判斷,如果新申請容量(cap)大于2倍的舊容量(old.cap),最終容量(newcap)就是新申請的容量(cap)
- 否則判斷,如果舊切片的長度小于1024,則最終容量(newcap)就是舊容量(old.cap)的兩倍,即(newcap=doublecap)
- 否則判斷,如果舊切片長度大于等于1024,則最終容量(newcap)從舊容量(old.cap)開始循環增加原來的 1/4,即(newcap=old.cap,for {newcap += newcap/4})直到最終容量(newcap)大于等于新申請的容量(cap),即(newcap >= cap)
追加元素append語法 slice=append(slice,elem1,elem2)
8.1 make()與new() 的區別
make()是Go語言中的內置函數,主要用于創建并初始化slice切片類型,或者map字典類型,或者channel通道類型數據。他與new方法的區別是。new用于各種數據類型的內存分配,在Go語言中認為他返回的是一個指針。指向的是一個某種類型的零值。make 返回的是一個有著初始值的非零值。
基本的區別是 new(T) 返回一個 *T ,返回的這個指針可以被隱式地消除引用 。而 make(T, args) 返回一個普通的T.
8.2 切片刪除
由于切片沒有刪除方法,因此我們需要通過切片的屬性進行刪除,例如:
slice:=[]int{1,2,3,4}
i := 2 // 要刪除的下標為2
slice = append(slice[:i], slice[i+1:]...) // 刪除中間1個元素
fmt.Println(slice) //結果[1 2 4]
參考文章:
https://juejin.cn/book/6844733833401597966/section/6844733833477111821