Go對應(yīng)的復(fù)合數(shù)據(jù)類型有數(shù)組,字典岩榆,指針错负,切片,通道勇边,結(jié)構(gòu)和結(jié)構(gòu)犹撒,他們字面類型如下:
[n] elementType //數(shù)組
map [keyType]valueType //字典
* pointerType //指針
[] elementType //切片
chan valueType //通道
struct {
fieldType fieldType
}
interface {
method1(inputParams)(returnParams)
}
? 指針
var a = 11
p := &a
type User struct{
name string
age int
}
andes := User{
name: "andes",
age: 18,
}
p := &andes
fmt.Println(p.name)
// Go不支持指針運(yùn)算
a := 1234
p := &a
p++ //不允許,error
//函數(shù)中允許返回局部變量地址
func sum (a, b int) *int {
sum := a + b
return &sum //允許粒褒,sum會被分配在heap上
}
? 數(shù)組
? 數(shù)組初始化
var arr [2]int //聲明
array := [...]float64{7.0, 8.0}
a := [3]int{1, 2, 3} //指定長度初始化
b := [...]int{4, 5, 7} //不指定長度初始化
c := [3]int{1:1, 2:3} //指定長度识颊,通過索引值初始化
d := [...]int{1:1, 2:3} //不指定長度,通過索引值初始化
? 數(shù)組特點(diǎn)
? 數(shù)組長度一旦創(chuàng)建就固定了奕坟,不可以追加元素
? 數(shù)組是值類型祥款,數(shù)組賦值或者作為函數(shù)參數(shù)都是值拷貝
a1 := [3]int{1, 2, 3}
a2 := a1
a2[0] = 11 //這里拷貝了一份
fmt.Println(a1) //[1, 2, 3]
fmt.Println(a2) // [11, 2, 3]
? 數(shù)組長度是數(shù)組類型的組成部分,[10]int和[20]int表示不同類型
? 可以根據(jù)數(shù)組創(chuàng)建切片
? 數(shù)組長度: len(array)
? 數(shù)組遍歷
a := [...]int{1, 2, 3}
b := a[0]
// 類似python遍歷
for i,v := range a {
fmt.Printlb(i)
}
alength := len(a)
for i:=0, i<alength; i++ {
}
? 切片
因?yàn)镚o的數(shù)組的長度定長和值拷貝限制了使用場景月杉,Go提供了slice刃跛,這是一種可變數(shù)組
// src/runtime/slice.go
type slice struct {
array unsafe.Pointer
len int
cap int
}
? 切片的創(chuàng)建
? 根據(jù)數(shù)組創(chuàng)建
// 創(chuàng)建語法array[a:b] 左邊包含,右邊不包含
var array = [...]int{1, 2, 3}
s1 := array[0:4]
? 根據(jù)內(nèi)置函數(shù)make創(chuàng)建切片
// len=10, cap=10
a := make([]int, 10)
// len=10, cap=15
a := make([]int, 10, 15)
? 切片的操作
? len()返回長度
? cap()返回容量
? append()追加元素
? copy()復(fù)制一個切片
a := [...]int{0, 1, 2, 3, 4}
b := make([]int, 2, 4)
c := a[0:3]
fmt.Println(len(b)) //2
fmt.Println(cap(b)) //4
b = append(b, 1)
fmt.Println(b) // [0, 0, 1]
fmt.Println(b) // 3
b = append(b, c)
fmt.Println(b) //[0, 0, 1, 0, 1, 2]
fmt.Println(len(b)) //6
fmt.Println(cap(b)) // 8, 底層數(shù)組發(fā)生自動擴(kuò)展
d := make([]int, 2, 2)
copy(d, c) //復(fù)制d和c長度最小的
fmt.Println(d) // [0, 1]
fmt.Println(len(d)) // 2
fmt.Println(cap(d)) // 2
? map
map[K]T苛萎,K必須是任意可以比較的類型桨昙,T是值類型,map是一種引用類型
? 創(chuàng)建Map
? 直接創(chuàng)建
dict := map[string]string{"a": "a1", "b": "b1"}
fmt.Println(dict["a"])
? 使用make函數(shù)創(chuàng)建
dict1 := make(map[int]int)
dict2 := make(map[int]int, 10) //初始化容量是10
dict1[1]=1
dict2[1]=1
? map標(biāo)準(zhǔn)操作
d1 := make(map[string]string, 10)
// 1. 賦值
d1["name"] = "chs"
// 2. 訪問值
fmt.Println(d1["name"])
// 3. range遍歷, 但是不能保證每次遍歷的順序是一樣的
for k, v := range mp {
fmt.Println("k=", k, "v=", v)
}
// 4. 刪除值
delete(d1, "name")
? map特殊操作
Go內(nèi)置的map不是并發(fā)安全的
// 如果map的value是一個復(fù)合對象腌歉,當(dāng)修改復(fù)合對象的值時候蛙酪,需要整體替換這個復(fù)合對象
type User struct {
name string,
arg int,
}
dict := make(map[string]User)
user := User{
name: "chs",
age: 18,
}
dict["chs"] = user
// dict["chs"].age = 29 //錯誤
user.age = 29
dict["chs"] = user //整體替換value
? struct
結(jié)構(gòu)的類型可以是任意類型,而且它的存儲空間是連續(xù)的究履,其中字段按照聲明的順序存放
struct的有兩種形式:
? struct類型的字面量
struct {
FieldName FieldType,
FieldName FieldType,
}
? 自定義struct類型
type TypeName struct {
FieldName FieldType,
FieldName FieldType,
}
struct字面量用的不是很多滤否,大多使用自定義類型的struct類型
? struct類型變量的初始化
package main
import "fmt"
type Person struct {
name string
age int
}
type Student struct {
*Person
number int
}
func main() {
p := &Person{
name: "chs",
age: 28,
}
s := Student{
Person: p,
number: 110,
}
fmt.Println(s.age) //這里Student通過struct間接繼承了Person
}
參考<<Go語言核心編程>>