Go核心语言编程 - 复合数据类型(3)

Go对应的复合数据类型有数组,字典,指针,切片,通道,结构和结构,他们字面类型如下:

[n] elementType //数组
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不支持指针运算
a := 1234
p := &a
p++ //不允许,error
//函数中允许返回局部变量地址
func sum (a, b int) *int {
    sum := a + b
    return &sum //允许,sum会被分配在heap上
}

• 数组
• 数组初始化

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} //不指定长度,通过索引值初始化

• 数组特点
• 数组长度一旦创建就固定了,不可以追加元素
• 数组是值类型,数组赋值或者作为函数参数都是值拷贝

a1 := [3]int{1, 2, 3}
a2 := a1
a2[0] = 11 //这里拷贝了一份
fmt.Println(a1) //[1, 2, 3]
fmt.Println(a2) // [11, 2, 3] 

• 数组长度是数组类型的组成部分,[10]int和[20]int表示不同类型
• 可以根据数组创建切片
• 数组长度: len(array)
• 数组遍历

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++ {
    
}

• 切片
因为Go的数组的长度定长和值拷贝限制了使用场景,Go提供了slice,这是一种可变数组

// src/runtime/slice.go
type slice struct {
    array unsafe.Pointer
    len int
    cap int
}

• 切片的创建
• 根据数组创建

// 创建语法array[a:b] 左边包含,右边不包含
var array = [...]int{1, 2, 3}
s1 := array[0:4]

• 根据内置函数make创建切片

// len=10, cap=10
a := make([]int, 10)
// len=10, cap=15
a := make([]int, 10, 15)

• 切片的操作
• len()返回长度
• cap()返回容量
• append()追加元素
• copy()复制一个切片

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, 底层数组发生自动扩展
d := make([]int, 2, 2)
copy(d, c) //复制d和c长度最小的
fmt.Println(d) // [0, 1]
fmt.Println(len(d)) // 2
fmt.Println(cap(d)) // 2

• map
map[K]T,K必须是任意可以比较的类型,T是值类型,map是一种引用类型
• 创建Map
• 直接创建

dict := map[string]string{"a": "a1", "b": "b1"}
fmt.Println(dict["a"])

• 使用make函数创建

dict1 := make(map[int]int)
dict2 := make(map[int]int, 10) //初始化容量是10
dict1[1]=1
dict2[1]=1

• map标准操作

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内置的map不是并发安全的
// 如果map的value是一个复合对象,当修改复合对象的值时候,需要整体替换这个复合对象

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
结构的类型可以是任意类型,而且它的存储空间是连续的,其中字段按照声明的顺序存放
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语言核心编程>>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,513评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,312评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,124评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,529评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,937评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,913评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,084评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,816评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,593评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,788评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,267评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,601评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,265评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,158评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,953评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,066评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,852评论 2 277