微吼云上線多路互動直播服務 加速多場景互動直播落地
726
2025-04-01
目錄
前言
布爾型
數字類型
字符串類型
使用[]byte修改
使用[]rune修改
指針類型
指針的簡單用法
修改指針值
復合類型
數組類型
結構體介紹
切片類型
從指定范圍生成切片
重置切片
直接聲明切片
Map
前言
Go語言數據類型包括布爾型、數字類型、字符串類型、復合類型這4種。其中復合類型又分為:數組類型、切片類型、Map類型以及結構體類型。
布爾型
與其他編程語言一樣,Go語言的布爾型只可以是true或者false。
下面,我們來舉例說明使用方式:
var x int=100 fmt.Println(x==100) fmt.Println(x!=100)
1
2
3
需要特別注意的是,Go語言對于值之間的比較有非常嚴格的限制,只有2相同類型的值才可以進行比較。如果值是接口,則它們必須實現相同的接口。如果其中一個值是常量,則另外一個值可以不是常量,但是類型和該常量必須相同。如果以上條件都不滿足,則必須將其中一個值的類型轉換為和另一個值相同的類型,才可以進行比較。
在Go語言中,and是 &&;or 是 ||。布爾值也不會被顯式的轉換為0或1,也不能被強制轉換成整型。如果你想把布爾型轉換為數字0或1,需要這樣寫:
func main() { var x int=100 fmt.Println(boolToInt(x==100)) fmt.Println(boolToInt(x!=100)) } func boolToInt(b bool) int{ if b{ return 1 } return 0 }
1
2
3
4
5
6
7
8
9
10
11
12
數字類型
Go語言支持非常多的數字類型,為了讓大家更加明了,博主專門列出了一張表格供大家參考。
需要注意的是,在32位操作系統上,int和uint均使用32位(4個字節);在64位操作系統上,它們均使用64位(8個字節)。
字符串類型
在Go語言中,字符串是由單個字節連接起來的,字節使用的是UTF-8編碼來表示Unicode文本。由于該編碼占用字節長度的不確定性,字符串也會根據需要占用1~4byte。
Go語言這樣做,不僅減少了內存和硬盤空間的占用,而且也不用像其他語言那樣需要對使用UTF-8字符集的文本進行編碼和解碼。
下面,我們先來看一段代碼:
str1 :="\"liyuanjing\"" + "str1" str2 :="liyuanjing\n" fmt.Print(str2) fmt.Print(str1)
1
2
3
4
5
如果大家運行上面這段代碼,就會發現str2輸出完成之后也會換行,要知道我們這里用的Print,并不是Println。所以,可以得出結論,Go語言字符串支持“\”轉義,但轉義字符會按意義默認輸出。同時,字符串也支持換行鏈接。
另外,Go語言的字符串,你可以默認看作一個數組,它可以通過“[]”寫入索引來獲取單個的字符。下面,我們來舉一個例子。
str1 :="liyuanjing" //獲取字符串索引1(位置2)的字符ASCII編碼 fmt.Println(str1[1]) //獲取字符串索引1(位置2)的字符 fmt.Println(string(str1[1])) //獲取字符串索引0到2的字符(不包括2) fmt.Println(str1[0:2]) //獲取字符串索引6開始的所有的字符 fmt.Println(str1[6:]) //獲取字符串索引0到2的字符(不包括2) fmt.Println(str1[:2]) //獲取字符串長度 fmt.Println(len(str1)) //獲取字符串所有字符的ASCII編碼 fmt.Println([]rune(str1)) //獲取字符串字符個數(長度) fmt.Println(utf8.RuneCountInString(str1))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
運行之后,輸出控制臺類型如下:
需要注意的是,在Go語言中,不能直接修改字符串,也就是不能通過str[1]的方式進行替換修改。如果你要修改,需要將字符串復制到一個可寫的變量中,一般是[]byte或[]rune,然后在進行修改。
使用[]byte修改
對于修改字符串的單個字符,可以直接通過[]byte進行修改。示例如下:
str :="liyuanjing" //復制 copyStr :=[]byte(str) //修改字符 copyStr[2]='Y' fmt.Printf("%s\n",str) fmt.Printf("%s\n",copyStr)
1
2
3
4
5
6
7
需要注意的是,單個字符用’ '單引號。運行之后,輸出如下:
使用[]rune修改
話不多說,這里直接上代碼。
str :="liyuanjing" //復制 copyStr :=[]rune(str) //修改字符 copyStr[2]='Y' fmt.Println(str) fmt.Println(string(copyStr))
1
2
3
4
5
6
7
運行之后的效果,如前文所示。
指針類型
學過C語言的應該很容易理解指針,它就是變量存儲的一個內存地址的變量類型。比如,大家可以把內存想象成一個順序存儲的方格(只是比喻)。
假如定義的a變量存儲6這個數,那么a肯定也在方格中,那么我們可以這樣定義指針指向a的內存地址。
var a int=6 var b *int=&a
1
2
指針的簡單用法
下面,我們來使用指針類型。在Go語言中,可以使用“%p”,輸出變量取地址后的指針值。
示例如下:
var a int=6 var b *int=&a fmt.Printf("%p\n",&a) fmt.Printf("%p",b)
1
2
3
4
運行之后,我們會發現這2個值是相等的,這是因為b存儲的本身就是指針值(地址),而通過&a取的也是a的地址,并不是值。如果你再輸入&b,意味著是指針的指針,也就是b的地址。(有點繞)
修改指針值
在每次學習心的編程語言時,讀者肯定都接觸過用一個臨時變量,交換2個變量的值。而修改指針同樣也需要這么操作。
func main() { a, b := 5, 8 exchange(&a, &b) fmt.Println(a, b) } func exchange(c, d *int) { t := *c *c = *d *d = t }
1
2
3
4
5
6
7
8
9
10
11
其實這跟Java與C中的方法,是參數還是參數的引用是一樣的。如果不是指針,只是值,這么做并不能改變原始參數的值。
復合類型
數組類型
數組在任何編程語言中,都是高頻使用的類型,所以學習時也要重點掌握。首先,就是掌握如何聲明數組與實例化數組,示例如下:
var name[SZIE] type //創建數組,但不初始化 var num[10] int //創建數組,并初始化 var num = [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
1
2
3
4
5
數組可以直接通過num[i]去修改訪問值,這里不再贅述。
結構體介紹
學過C語言的,對結構體應該并不陌生。其實Go語言的結構體與C基本差不多,下面,我們來看看如何定義以及使用:
//語法 type 類型名 struct{ 字段1 類型1 字段2 類型2 //..... } //定義 type User struct { name string age int }
1
2
3
4
5
6
7
8
9
10
11
接著,我們再來看看定義并賦值后,如何使用結構體。
示例如下:
type User struct { name string age int } func main() { var lyj User=User{name:"liyuanjing",age:29} var fxy User=User{name:"fengxinyao",age:31} fmt.Println(lyj) fmt.Println(fxy) fmt.Println(lyj.age) fmt.Println(fxy.name) }
1
2
3
4
5
6
7
8
9
10
11
12
13
運行之后,效果如下:
可以發現,我們可以直接把結構體當作一個類型來使用。也就是說,在Go語言中,我們可以自己通過結構體定義數據類型。
而使用結構體,可以直接輸出,也可以通過[變量.屬性]的方式,獲取結構體中的單個值。同樣的,結構體也可以時指針變量,這一點與C語言一樣。
切片類型
切片(slice)是對數組的一個連續“片段”的引用,所以切片也可以看作一個引用類型,或者相當于Python中的list。
切片的內部結構包含內存地址、大小以及內容,一般用于快速地操作一塊數據集合。如下圖所示:
其中,切片的指針指向數組,長度代表當前切片的長度,容量是當前切片的容量。容量總是大于或等于切片的長度,而且切片默認指向一段連續的內存區域。
切片與數組密不可分,如果將數組理解為一棟火車廂,那么切片就是把不同連續車廂出租給使用者。在出租的過程中,需要選擇開始車廂與結束車廂,這個過程就會生成切片。示例如下:
var sliceBuilder [10]int for i :=0;i<10;i++{ sliceBuilder[i]=i+1 } fmt.Println(sliceBuilder[5:7]) fmt.Println(sliceBuilder[8:]) fmt.Println(sliceBuilder[:5])
1
2
3
4
5
6
7
運行之后,控制臺輸出如下:
看過前面字符串獲取子字符串的用戶,肯定會問,切片有何區別?
怎么說呢?切片有點像C語言的指針。指針可以做運算,但代價是內存操作越界。切片在指針的基礎上增加了大小,約束了切片對應的內存區域。
在切片的使用過程中,無法對切片內部的地址和大小進行手動調整,因此切片比指針更安全強大。
如果把切片開始與結束位置都設置為0,則生成的切片將變空,代碼如下:
var sliceBuilder [10]int for i :=0;i<10;i++{ sliceBuilder[i]=i+1 } fmt.Println(sliceBuilder[0:0])
1
2
3
4
5
記住是清空,不是全部賦值為0,也就是說充值的切片沒有任何元素。運行之后,效果如下:
切片也是可以直接被聲明的,并不一定需要從數組操作。其語法如下:
var name []Type
1
注意,這個看上去與數組聲明的方式差不多,但有本質區別,不信的讀者回頭看看上面的數組。數組定義必須給定你需要創建一個多少元素的數組,而切片不需要。
示例:
var sliceInt []int var sliceString []string var emptySlice =[]int{} fmt.Println(sliceInt,sliceString,emptySlice) fmt.Println(len(sliceInt),len(sliceString),len(emptySlice)) fmt.Println(sliceString==nil) fmt.Println(sliceInt==nil) fmt.Println(emptySlice==nil)
1
2
3
4
5
6
7
8
運行之后,效果如下:
需要注意的是,切片是動態結構,只能與nil判定相等,不能互相判定相等。在聲明了切片之后,可以使用append()方法向切片中添加元素。如果需要創建一個指定長度的切片,則可以使用make()方法創建。
sliceInt :=make([]int,6,10) fmt.Println(sliceInt)
1
2
上面聲明了一個長度為6,容量為10的切片,控制臺會輸出6個0的切片。
用make()函數生成的切片會發生內存分配操作。但如果給定了開始與結束位置(包括切片復位)的切片,則只是將新的切片結構指向已經分配的內存區域。設置開始與結束位置,不會發生內存分配操作。
Map
Map就是“鍵值對”的無序集合。元素包含一個key,與一個Value。有時候也會成為字典。其定義的語法如下:
var student map[string]string var user = map[string]string{"liyuanjing": "29", "fengxiangyao": "29"} student =make(map[string]string)//刪除這行在測試 student["liyuanjing"] = "29" fmt.Println(student) fmt.Println(user)
1
2
3
4
5
6
運行之后,控制臺輸出如下:
如上面注釋一樣,如果刪除make函數那一樣,肯定會報錯。這是因為在聲明student 后并未初始化它,所以它的值是nil,不指向任何內存地址。需要通過make方法分配確定的內存地址,程序修改后即可正常運行。
在我們的項目中,有時候Key并不僅僅只對應一個Value,如果要key對應多個值,那么Map應該怎么做?示例如下:
map1 := make(map[int][]int) map1[22]=[]int{1,2,3,4,5} fmt.Println(map1)
1
2
3
運行之后,效果如下:
Go web前端 數據結構
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。