Go语言学习笔记2019.11.28


复合类型

分类

类型 | 名称 | 长度 | 默认值 | 说明
pointer | 指针 | | nil |
array | 数组 | | 0 |
slice | 切片 | | nil | 引用类型
map | 字典 | | nil | 引用类型
struct | 结构体 | | |

指针

指针是代表某个内存地址的值,这个内存地址往往是在内存中存储的另一个变量的值的起始位置。

基本操作

func main() {
    var a int = 10
    // 每个变量有两层含义:变量的内存和变量的地址
    fmt.Printf("a = %d\n", a)  // 变量的内存
    fmt.Printf("a = %v\n", &a)  // 变量的地址
    
    // 保存某个变量的地址,需要指针类型 
    // *int 用以保存 int 的地址
    // **int 用以保存 *int 的地址
    var p *int
    p = &a // 指针变量指向谁,就把谁的地址赋值给指针变量
    
    *p = 666 // *p操作的不是p的内存,而是p所指向的内存(既是a)
}

不要操作没有合法指向的内存。

new函数

var p *int //指向一个合法内存
p = new(int) // p是*int,指向int类型
*p = 666
q := new(int) // 自动推导类型
*q = 777

地址传递

func swap(p1, p2 *int) {
    *p1, *p2 = *p2, *p1
}
func main() {
    a, b := 10, 20
    
    swap(&a, &b)
}

数组

为什么需要数组

数组:同一类型数据的集合。
通过下标操作数组,从0开始,到 len()-1

数组定义

func main() {
    // 定义一个数组,[10]int和[5]int是不同类型
    // [数字],这个数字作为数组元素个数
    var a [10]int
    var b [5]int
    // 注意:定义数组时,指定的数组元素个数必须是常量
    // 数组下标可以是变量或常量
}

数组初始化

初始化:声明定义的同时赋值

func main() {

    // 全部初始化
    var a [5]int = [5]int{1, 2, 3, 4, 5}
    b := [5]int{1, 2, 3, 4, 5}
    
    // 部分初始化,没有初始化的元素自动赋值为0
    c := [5]int{1, 2, 3}
    
    // 指定某个元素初始化
    d := [5]int{2: 10, 4: 20 }
}

二维数组

var a [3][4]int
var b [3][4]int
b := [3][4]int{{1,2,3,4},    {5,6,7,8},    {9,10,11,12}}
// 部分初始化,没有初始化的为0
b := [3][4]int{{1,2,3,4},    {5,6,7,8},    {9,10}}

数组比较和赋值

只支持 == 和 != 的比较,用于比较两个数组类型、每个元素都一样。

map

map(映射、字典)是一种内置的数据结构,它是一个无序的key-value对的集合。

map创建和初始化

map只有len,没有cap

// 先声明,后赋值
var m1 map[int]string

// 通过make创建,可以指定长度,只是指定了容量,但是数据为空
// 超出预设容量时,会自动扩容
m2 := make(map[int]string, 10)

// 键名是唯一的
info := map[int]string{
    110: "mike",
    111: "yoyo",
    112: "lily"
}

map常用操作

赋值

    m1 := map[int]string{1:"mike", 2:"yoyo"}
    // 重复键名赋值,会进行覆盖
    m1[1] = "c++"
    // 追加元素时,map底层自动增加内存,和append类似
    m1[3] = "go"

遍历

m := map[int]string{1:"mike", 2:"yoyo", 3:"go"}
// 第一个返回值为key,第二个返回值为value,遍历结果是无序的
for key, value := range m {
    fmt.Printf("%d ====> %s\n", key, value)
}

判断key是否存在

// 第一个值为key所对应的value,第二个返回值为key是否存在的状态,true或者false
value, ok := m[1]

删除

// 删除m中key为1的内容
delete(m,1)

map做参数

map做函数参数时,是引用传递。

结构体

结构体普通变量初始化

// 定义一个结构体类型
type Student struct {
    id int
    name string
    sex byte
    age int
    attr string
}
func main(){
    // 顺序初始化,每个成员都必须初始化
    var s1 Student = Student{1, "mike", 'm', 18, "bj"}
    // 指定成员初始化,没有初始化的成员自动赋值为0
    s2 := Student{name: "mike", addr:"bj"}
}

结构体指针变量初始化

// 定义一个结构体类型
type Student struct {
    id int
    name string
    sex byte
    age int
    attr string
}
func main(){
    var p1 *Student = &Student{1, "mike", 'm', 18, "bj"}
    p2 := &Student{name: "mike", addr:"bj"}
}

结构体普通变量成员的使用

// 定义一个结构体类型
type Student struct {
    id int
    name string
    sex byte
    age int
    attr string
}
func main(){
    // 定义一个结构体普通变量
    var s Student
    // 操作成员需要使用点(.)运算符
    s.id = 1
    s.name = "mike"
    s.sex = 'm' // 字符
    s.sddr = "bj"
}

结构体指针变量成员的使用

// 定义一个结构体类型
type Student struct {
    id int
    name string
    sex byte
    age int
    attr string
}
func main(){
    // 1、指针有合法指向后,才操作变量
    // 先定义一个结构体普通变量
    var s Student
    // 再定义一个指针变量,保存s的地址
    var p1 *Student
    p1 = &s
    
    // 通过指针操作成员,p1.id和(*p1).id完全等价,只能使用点(.)运算符
    p1.id = 18
    (*p1).name = "mike" // 与上面等价
    
    // 2、通过new来申请一个结构体
    p2 := new(Student)
    p2.id = 1
    p2.name = "mike"
}

结构体比较和赋值

// 定义一个结构体类型
type Student struct {
    id int
    name string
    sex byte
    age int
    attr string
}
func main(){
    s1 := Student{1, "mike", 'm', 18, "bj"}
    s2 := Student{1, "mike", 'm', 18, "bj"}
    s3 := Student{2, "mike", 'm', 18, "bj"}
    
    fmt.Println("s1  == s2 ",s1  == s2)
    fmt.Println("s1  == s3 ",s1  == s3)
    
    // 同类型的两个结构体可以相互赋值
    var tmp Student
    tmp = s3
}

结构体做函数参数

可以值传递和地址传递。

可见性

如果想使用别的包的函数、结构体类型、结构体成员,
函数名、类型名、结构体成员变量名的首字母必须大写、可见,
如果首字母是小写,只能在同一个包里使用。

用谁谁首字母大写

本文发表于2019年11月28日 21:56
阅读 276 讨论 0 喜欢 0

讨论

周娱

君子和而不同
按照自己的方式,去度过人生

8027 3840859
抢先体验

扫码体验
趣味小程序
文字表情生成器

加入组织

扫码添加周娱微信
备注“加入组织”
邀请进开发群

闪念胶囊

人活一辈子,不是一年两年。时间是有连续性的,做抉择的时候要多看几步。保持警惕,大丈夫有所为,有所不为。

跟人接触,不要想:我能从你身上得到什么,要想:我能给你什么。 想通了,内核就稳了。

这个世界上,别人只会看你现在的样子而不是以后的样子。你以后的样子只有自己才相信。如果没有执行力,一切都是虚妄。

对普通人来说,人和人相处其实最重要的是感觉。感觉不好,你说什么都没用,怎么解释都没用,越说越错,反正最后不好的锅都往你身上扣。所谓“说你行你就行,不行也行。说你不行,你就不行,行也不行”就是这个意思。狼要吃人根本不需要理由,你也同样叫不醒装睡的人。遇到这种情况,早点闪人才是上策。不过大部分人的问题是没有闪人的心态,能力,和资源。

考985不牛逼,考上才牛逼。创业不牛逼,创业成功才牛逼。这个社会上很多人把目标当成牛逼的资本,牛逼哄哄的,死活不听劝,然后做的一塌糊涂,给别人添麻烦,让别人帮他料理后事,对此只能呵呵。

当你尝到用生气解决问题的甜头后,你就懒得再用其他方式了。你却忽略了,生气是鸩毒啊,剂量用够了,你的关系也玩完了。

年轻的时候你只搞事业不谈恋爱,等你事业有成了,钱相对自由了,你可能已经没有荷尔蒙了。

如果你经常雇佣比你矮小的人,将来我们就会变成矮人国,变成一家侏儒公司。相反,如果你每次都雇用比你高大的人,日后我们必能成为一家巨人公司。

如果一个人有充裕的时间去完成一项工作,那么他就会放慢节奏或者增加其他不必要的工作,直到花光所有的时间。

Copyright © 2016 - 2020 Cion.
All Rights Reserved.
备案:鲁ICP备19012333号-4.