<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
在 Go 語言中,同時宣告多個常數、變數,或者匯入多個包時,可採用分組的方式進行宣告。
例如下面的程式碼:
import "fmt" import "os" const i = 100 const pi = 3.1415 const prefix = "Go_" var i int var pi float32 var prefix string1
可以改成下面的方式:
import( "fmt" "os" ) const( i = 100 pi = 3.1415 prefix = "Go_" ) var( i int pi float32 prefix string )
Go 裡面有一個關鍵字 iota,這個關鍵字用來宣告 enum 的時候採用,它預設開始值是 0,每呼叫一次加 1:
const( x = iota // x == 0 y = iota // y == 1 z = iota // z == 2 w // 常數宣告省略值時,預設和之前一個值的字面相同。 //這裡隱式地說 w = //iota,因此 w == 3。其實上面 y 和 z 可同樣不用"= iota" )
注:const v = iota // 每遇到一個 const 關鍵字,iota 就會重置,此時 v == 0。
Go 之所以會那麼簡潔,是因為它有一些預設的行為:
class
中的帶 public 關鍵詞的公有函數;小寫字母開頭的就是有 private 關鍵詞的私有函數。array 就是陣列,它的定義方式如下:
var arr [n]type
在[n]type
中,n 表示陣列的長度,type 表示儲存元素的型別。對陣列的操作和其它語言類似,都是通過[]來進行讀取或賦值:
var arr [10]int // 宣告了一個 int 型別的陣列 arr[0] = 42 // 陣列下標是從 0 開始的 arr[1] = 13 // 賦值操作 fmt.Printf("The first element is %dn", arr[0]) // 獲取資料,返回 42 fmt.Printf("The last element is %dn", arr[9]) //返回未賦值的最後一個元素,預設返回 0
由於長度也是陣列型別的一部分,因此[3]int 與[4]int 是不同的型別,陣列也就不能改變長度。
陣列之間的賦值是值的賦值,即當把一個陣列作為引數傳入函數的時候,傳入的其實是該陣列的副本,而不是它的指標。
如果要使用指標,那麼就需要用到後面介紹的 slice 型別了。
陣列可以使用另一種:=來宣告。
a := [3]int{1, 2, 3} // 宣告了一個長度為 3 的 int 陣列 b := [10]int{1, 2, 3} // 宣告了一個長度為 10 的 int 陣列,其中前三個元素初始化為 1、2、3,其它預設 為 0 c := [...]int{4, 5, 6} // 可以省略長度而採用`...`的方式,Go 會自動根據元素個數來計算長度
也許你會說,我想陣列裡面的值還是陣列,能實現嗎?
當然咯,Go 支援巢狀陣列,即多維 陣列。
比如下面的程式碼就宣告了一個二維陣列:
// 宣告了一個二維陣列,該陣列以兩個陣列作為元素,其中每個陣列中又有 4 個 int 型別的元素 doubleArray := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}} // 如果內部的元素和外部的一樣,那麼上面的宣告可以簡化,直接忽略內部的 型別 easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}
陣列的分配如下所示:
在很多應用場景中,陣列並不能滿足我們的需求。在初始定義陣列時,我們並不知道需要多大的陣列,因此我們就需要“動態陣列”。在 Go 裡面這種資料結構叫 slice , 翻譯過來就是切片的意思,大白話就是切成一片一片的:
// 和宣告 array 一樣,只是少了長度 var fslice []int
接下來我們可以宣告一個 slice,並初始化資料,如下所示:
slice := []byte {'a', 'b', 'c', 'd'}
slice
可以從一個陣列或一個已經存在的 slice 中再次宣告。// 宣告一個含有 10 個元素元素型別為 byte 的陣列 var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} // 宣告兩個含有 byte 的 slice var a, b []byte // a 指向陣列的第 3 個元素開始,併到第五個元素結束, a = ar[2:5] //現在 a 含有的元素: ar[2]、ar[3]和 ar[4] // b 是陣列 ar 的另一個 slice b = ar[3:5] // b 的元素是:ar[3]和 ar[4]
注意 slice 和陣列在宣告時的區別:
它們的資料結構如下所示:
slice 有一些簡便的操作:
下面這個例子展示了更多關於 slice 的操作:
// 宣告一個陣列 var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} // 宣告兩個 slice var aSlice, bSlice []byte // 演示一些簡便操作 aSlice = array[:3] // 等價於 aSlice = array[0:3] aSlice 包含元素: a,b,c aSlice = array[5:] // 等價於 aSlice = array[5:10] aSlice 包含元素: f,g,h,i,j aSlice = array[:] // 等價於 aSlice = array[0:10] 這樣 aSlice 包含了全部的元素 // 從 slice 中獲取 slice aSlice = array[3:7] // aSlice 包含元素: d,e,f,g,len=4,cap=7 bSlice = aSlice[1:3] // bSlice 包含 aSlice[1], aSlice[2] 也就是含有: e,f bSlice = aSlice[:3] // bSlice 包含 aSlice[0], aSlice[1], aSlice[2] 也就是 含有: d,e,f bSlice = aSlice[0:5] // 對 slice 的 slice 可以在 cap 範圍內擴充套件,此時 bSlice 包含:d,e,f,g,h bSlice = aSlice[:] // bSlice 包含所有 aSlice 的元素: d,e,f,g
slice
是參照型別,所以當參照改變其中元素的值時,其它的所有參照都會改變該值,例如上面的aSlice 和bSlice,如果修改了aSlice中元素的值,那麼 bSlice相對應的值也會改變。 從概念上面來說 slice像一個結構體,這個結構體包含了三個元素:
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} Slice_a := Array_a[2:5]
上面程式碼的真正儲存結構如下圖所示:
對於 slice 有幾個有用的內建函數:
注:append 函數會改變 slice 所參照的陣列的內容,從而影響到參照同一陣列的其它 slice。
但當 slice 中沒有剩餘空間(即(cap-len) == 0)時,此時將動態分配新的陣列空間。
返回的slice 陣列指標將指向這個空間,而原陣列的內容將保持不變;
其它參照此陣列的 slice 則不受影響。
map 也就是 Python 中字典的概念,它的格式為 map[keyType]valueType我們看下面的程式碼,map 的讀取和設定也類似 slice 一樣,通過 key 來操作,只是 slice 的index只能是int型別,而 map 多了很多型別,可以是 int,可以是 string 及所有完全定
義了==與!=操作的型別。
// 宣告一個 key 是字串,值為 int 的字典,這種方式的宣告需要在使用之前使用 make 初始化 var numbers map[string] int // 另一種 map 的宣告方式 numbers := make(map[string]int) numbers["one"] = 1 //賦值 numbers["ten"] = 10 //賦值 numbers["three"] = 3 fmt.Println("第三個數位是: ", numbers["three"]) // 讀取資料 // 列印出來如:第三個數位是: 3
這個 map 就像我們平常看到的表格一樣,左邊列是 key,右邊列是值使用 map 過程中需要注意的幾點:
map 的初始化可以通過 key:val 的方式初始化值,同時 map 內建有判斷是否存在 key 的方式,通過 delete 刪除 map 的元素:
// 初始化一個字典 rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 } // map 有兩個返回值,第二個返回值,如果不存在 key,那麼 ok 為 false,如果存在 ok 為 true csharpRating, ok := rating["C#"] if ok { fmt.Println("C# is in the map and its rating is ", csharpRating) } else { fmt.Println("We have no rating associated with C# in the map") } delete(rating, "C") // 刪除 key 為 C 的元素
上面說過了,map 也是一種參照型別,如果兩個 map 同時指向一個底層,那麼一個改變, 另一個也相應的改變:
m := make(map[string]string) m["Hello"] = "Bonjour" m1 := m m1["Hello"] = "Salut" // 現在 m["hello"]的值已經是 Salut 了
關於“零值”,所指並非是空值,而是一種“變數未填充前”的預設值,通常為0。 此處羅列部分型別 的“零值”。
int 0 int8 0 int32 0 int64 0 uint 0x0 rune 0 //rune 的實際型別是 int32 byte 0x0 // byte 的實際型別是 uint8 float32 0 //長度為 4 byte float64 0 //長度為 8 byte bool false string ""
到此這篇關於GO中 分組宣告與array, slice, map函數的文章就介紹到這了,更多相關GO分組宣告與array, slice, map內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45