<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Go 語言資料型別包含基礎型別和複合型別兩大類。
基礎型別包括:
複合型別包括:
下面用程式碼加註釋的方式說明:
宣告一個bool型別的變數,只有true和false兩個值,初始值為false
var isLogin bool // 宣告一個int型別的變數,初始值為0 //(int8,int16,int32 uint8,uint16....類似,只是有符號和無符號的區別) // 最常用的就是int,如果需要更大的範圍可以用int64或者uint64 var count int // 宣告一個string型別的變數,初始值為"" var s string //宣告一個byte型別的變數 var b byte //宣告一個rune型別的變數 //int32的別名,表示單個Unicode字元 var r rune
go的指標和c語言的指標型別,都是表示一個變數的地址,不同的是,go的指標要比c的指標簡單的多,老規矩,程式碼註釋,如下:
package main import "fmt" func main() { var count = 100 //定義變數count var ptr *int //定義一個指標ptr,此指標可以儲存int型別變數的地址 ptr = &count //ptr儲存的是變數count的地址, & 符號是取變數地址的符號 fmt.Println("count=",count) //列印count的值 fmt.Println("ptr=", *ptr) //列印ptr指向的變數的值,此句列印100 }
執行結果如下:
count= 100
ptr= 100
陣列為一組相同資料型別資料的集合,大小固定,不能更改,每個元素稱為element,宣告的陣列元素預設值都是對應型別的0值。而且陣列在Go語言中是一個值型別(value type)所有值型別變數在賦值和作為引數傳遞時都會產生一次複製動作,即對原值的拷貝
package main import "fmt" func main() { // 1.宣告後賦值 (var <陣列名稱> [<陣列長度>]<陣列元素>) var arr [2]int // 陣列元素的預設值都是 0 fmt.Println(arr) // 輸出:[0 0] arr[0] = 1 arr[1] = 2 fmt.Println(arr) // 輸出:[1 2] // 2.宣告並賦值 (var <陣列名稱> = [<陣列長度>]<陣列元素>{元素1,元素2,...}) var intArr = [2]int{1, 2} strArr := [3]string{`aa`, `bb`, `cc`} fmt.Println(intArr) // 輸出:[1 2] fmt.Println(strArr) // 輸出:[aa bb cc] // 3.宣告時不設定大小,賦值後語言本身會計算陣列大小 // var <陣列名稱> [<陣列長度>]<陣列元素> = [...]<元素型別>{元素1,元素2,...} var arr1 = [...]int{1, 2} arr2 := [...]int{1, 2, 3} fmt.Println(arr1) // 輸出:[1 2] fmt.Println(arr2) // 輸出:[1 2 3] //arr1[2] = 3 // 編譯報錯,陣列大小已設定為2 // 4.宣告時不設定大小,賦值時指定索引 // var <陣列名稱> [<陣列長度>]<陣列元素> = [...]<元素型別>{索引1:元素1,索引2:元素2,...} var arr3 = [...]int{1: 22, 0: 11, 2: 33} arr4 := [...]string{2: "cc", 1: "bb", 0: "aa"} fmt.Println(arr3) // 輸出:[11 22 33] fmt.Println(arr4) // 輸出:[aa bb cc] // 遍歷陣列 for i := 0; i < len(arr4); i++ { v := arr4[i] fmt.Printf("i:%d, value:%sn", i, v) } }
因為陣列的長度定義後不可修改,所以需要切片來處理可變長陣列資料。切片可以看作是一個可變長的陣列,是一個參照型別。
它包含三個資料:
注:瞭解c++和java的同學,可以參考vector和List,切片就是類似這兩個資料結構,直接上程式碼:
package main import "fmt" func main() { var sl []int // 宣告一個切片 sl = append(sl, 1, 2, 3) // 往切片中追加值 fmt.Println(sl) // 輸出:[1 2 3] var arr = [5]int{1, 2, 3, 4, 5} // 初始化一個陣列 var sl1 = arr[0:2] // 冒號:左邊為起始位(包含起始位資料),右邊為結束位(不包含結束位資料);不填則預設為頭或尾 var sl2 = arr[3:] var sl3 = arr[:5] fmt.Println(sl1) // 輸出:[1 2] fmt.Println(sl2) // 輸出:[4 5] fmt.Println(sl3) // 輸出:[1 2 3 4 5] sl1 = append(sl1, 11, 22) // 追加元素 fmt.Println(sl1) // 輸出:[1 2 11 22] }
使用make關鍵字直接建立切片,
語法:make([]型別, 大小,預留空間大小),make() 函數用於宣告slice切片、map字典、channel通道。
如下:
package main import "fmt" func main() { var s1 = make([]int, 5) // 定義元素個數為5的切片 s2 := make([]int, 5, 10) // 定義元素個數5的切片,並預留10個元素的儲存空間(預留空間不知道有什麼用?) s3 := []string{`aa`, `bb`, `cc`} // 直接建立並初始化包含3個元素的陣列切片 fmt.Println(s1, len(s1)) // 輸出:[0 0 0 0 0] 5 fmt.Println(s2, len(s2)) // 輸出:[0 0 0 0 0] 5 fmt.Println(s3, len(s3)) // [aa bb cc] 3 s1[1] = 1 // 宣告或初始化大小中的資料,可以指定賦值 s1[4] = 4 //s1[5] = 5 // 編譯報錯,超出定義大小 s1 = append(s1, 5) // 可以追加元素 fmt.Println(s1, len(s1)) // 輸出:[0 1 0 0 4 5] 6 s2[1] = 1 s2 = append(s2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) fmt.Println(s2, len(s2)) // 輸出:[0 1 0 0 0 1 2 3 4 5 6 7 8 9 10 11] 16 // 遍歷切片 for i := 0; i < len(s2); i++ { v := s2[i] fmt.Printf("i: %d, value:%d n", i, v) } }
map
是一種鍵值對的無序集合,與 slice
類似也是一個參照型別。map 本身其實是個指標,指向記憶體中的某個空間。
宣告方式與陣列類似,宣告方式:var 變數名 map[key型別值型別 或直接使用 make 函數初始化:make(map[key型別]值型別, 初始空間大小)。
其中key值可以是任何可以用==判斷的值型別,對應的值型別沒有要求。
直接上程式碼,如下:
package main import ( "fmt" "unsafe" ) func main() { // 宣告後賦值 var m map[int]string fmt.Println(m) // 輸出空的map:map[] //m[1] = `aa` // 向未初始化的map中賦值報錯:panic: assignment to entry in nil map // 宣告並初始化,初始化使用{} 或 make 函數(建立型別並分配空間) var m1 = map[string]int{} var m2 = make(map[string]int) m1[`a`] = 11 m2[`b`] = 22 fmt.Println(m1) // 輸出:map[a:11] fmt.Println(m2) // 輸出:map[b:22] // 初始化多個值 var m3 = map[string]string{"a": "aaa", "b": "bbb"} m3["c"] = "ccc" fmt.Println(m3) // 輸出:map[a:aaa b:bbb c:ccc] // 刪除 map 中的值 delete(m3, "a") // 刪除鍵 a 對應的值 fmt.Println(m3) // 輸出:map[b:bbb c:ccc] // 查詢 map 中的元素 v, ok := m3["b"] if ok { fmt.Println(ok) fmt.Println("m3中b的值為:", v) // 輸出:m3中b的值為: bbb } // 或者 if v, ok := m3["b"]; ok { // 流程處理後面講 fmt.Println("m3中b的值為:", v) // 輸出:m3中b的值為: bbb } fmt.Println(m3["c"]) // 直接取值,輸出:ccc // map 中的值可以是任意型別 m4 := make(map[string][5]int) m4["a"] = [5]int{1, 2, 3, 4, 5} m4["b"] = [5]int{11, 22, 33} fmt.Println(m4) // 輸出:map[a:[1 2 3 4 5] b:[11 22 33 0 0]] fmt.Println(unsafe.Sizeof(m4)) // 輸出:8,為8個位元組,map其實是個指標,指向某個記憶體空間 }
說到通道 channel
,則必須先了解下 Go 語言的 goroutine
協程(輕量級執行緒)。channel就是為 goroutine 間通訊提供通道。goroutine
是 Go 語言提供的語言級的協程,是對 CPU 執行緒和排程器的一套封裝。
channel
也是型別相關的,一個 channel 只能傳遞一種型別的值。
宣告:var 通道名 chan 通道傳遞值型別 或 make 函數初始化:make(chan 值型別, 初始儲存空間大小)
說白了,通道類似訊息佇列,主要應用在並行程式設計裡面比較多,
直接上程式碼,如下:
package main import ( "fmt" "time" ) func main() { var ch1 chan int // 宣告一個通道 ch1 = make(chan int) // 未初始化的通道不能儲存資料,初始化一個通道 ch2 := make(chan string, 2) // 宣告並初始化一個帶緩衝空間的通道 // 通過匿名函數向通道中寫入資料,通過 <- 方式寫入 go func() { ch1 <- 1 }() go func() { ch2 <- `a` }() v1 := <-ch1 // 從通道中讀取資料 v2 := <-ch2 fmt.Println(v1) // 輸出:1 fmt.Println(v2) // 輸出:a // 寫入,讀取通道資料 ch3 := make(chan int, 1) // 初始化一個帶緩衝空間的通道 go readFromChannel(ch3) go writeToChannel(ch3) // 主執行緒休眠1秒,讓出執行許可權給子 Go 程,即通過 go 開啟的 goroutine,不然主程式會直接結束 time.Sleep(1 * time.Second) } func writeToChannel(ch chan int) { for i := 1; i < 10; i++ { fmt.Println("寫入:", i) ch <- i } } func readFromChannel(ch chan int) { for i := 1; i < 10; i++ { v := <-ch fmt.Println("讀取:", v) } }
執行結果如下:
// ------ 輸出:--------
1
a
寫入: 1
寫入: 2
寫入: 3
讀取: 1
讀取: 2
讀取: 3
寫入: 4
寫入: 5
寫入: 6
讀取: 4
讀取: 5
讀取: 6
寫入: 7
寫入: 8
寫入: 9
讀取: 7
讀取: 8
讀取: 9
goroutine
和 channel
的詳細用法會有相應的部落格專門來講這一章節,具體可在我的個人主頁裡面,找一下相關的部落格參考。
結構體是一種聚合的資料型別,是由零個或多個任意型別的值聚合成的實體。每個值稱為結構體的成員,和java中的class是一個意思:
package main import "fmt" // 定義一個結構體 person type person struct { name string age int } func main() { var p person // 宣告一個 person 型別變數 p p.name = "max" // 賦值 p.age = 12 fmt.Println(p) // 輸出:{max 12} p1 := person{name: "mike", age: 10} // 直接初始化一個 person fmt.Println(p1.name) // 輸出:mike p2 := new(person) // new函數分配一個指標,指向 person 型別資料 p2.name = `張三` p2.age = 15 fmt.Println(*p2) // 輸出:{張三 15} }
介面用來定義行為。Go 語言不同於物件導向語言,沒有類的概念,也沒有傳統意義上的繼承。Go 語言中的介面,用來定義一個或一組行為,某些物件實現了介面定義的行為,則稱這些物件實現了(implement)該介面,型別即為該介面型別。
定義介面也是使用 type 關鍵字,格式為:
// 定義一個介面 type InterfaceName interface { FuncName1(paramList) returnType FuncName2(paramList) returnType ... }
實列:
package main import ( "fmt" "strconv" ) // 定義一個 Person 介面 type Person interface { Say(s string) string Walk(s string) string } // 定義一個 Man 結構體 type Man struct { Name string Age int } // Man 實現 Say 方法 func (m Man) Say(s string) string { return s + ", my name is " + m.Name } // Man 實現 Walk 方法,strconv.Itoa() 數位轉字串 func (m Man) Walk(s string) string { return "Age: " + strconv.Itoa(m.Age) + " and " + s } func main() { var m Man // 宣告一個型別為 Man 的變數 m.Name = "Mike" // 賦值 m.Age = 30 fmt.Println(m.Say("hello")) // 輸出:hello, my name is Mike fmt.Println(m.Walk("go work")) // 輸出:Age: 30 and go work jack := Man{Name: "jack", Age: 25} // 初始化一個 Man 型別資料 fmt.Println(jack.Age) fmt.Println(jack.Say("hi")) // 輸出:hi, my name is jack }
error 型別本身是 Go 語言內部定義好的一個介面,介面裡定義了一個 Error() 列印錯誤資訊的方法,原始碼如下:
type error interface { Error() string }
自定義錯誤資訊:
package main import ( "errors" "fmt" ) func main() { // 使用 errors 客製化錯誤資訊 var e error e = errors.New("This is a test error") fmt.Println(e.Error()) // 輸出:This is a test error // 使用 fmt.Errorf() 客製化錯誤資訊 err := fmt.Errorf("This is another error") fmt.Println(err) // 輸出:This is another test error }
到此這篇關於Go語言資料型別詳細介紹的文章就介紹到這了,更多相關Go資料型別內容請搜尋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