golang学习,小结
切片
切片,底层就是数组,len(切片的长度)和cap(容量,切片的空间)
从一个数组来得到切片,修改切片会修改原来的数组,数据会收到影响
我们可以通过内置的 append 函数对一个切片追加元素,返回新切片
append 函数可以有以上三种操作,你可以根据自己的实际需求进行选择,append 会自动处理切片容量不足需要扩容的问题。
小技巧:在创建新切片的时候,最好要让新切片的长度和容量一样,这样在追加操作的时候就会生成新的底层数组,从而和原有数组分离,就不会因为共用底层数组导致修改内容的时候影响多个切片。
map
Go 语言的 map 可以获取不存在的 K-V 键值对,如果 Key 不存在,返回的 Value 是该类型的零值,比如 int 的零值就是 0。所以很多时候,我们需要先判断 map 中的 Key 是否存在。
map 的 [] 操作符可以返回两个值:
- 第一个值是对应的 Value;
- 第二个值标记该 Key 是否存在,如果存在,它的值为 true。
和数组切片不一样,map 是没有容量的,它只有长度,也就是 map 的大小(键值对的个数)。要获取 map 的大小,使用内置的 len 函数
string和[]byte
字符串 string 也是一个不可变的字节序列,所以可以直接转为字节切片 []byte
而在 UTF8 编码下,一个汉字对应三个字节,把一个汉字当成一个长度计算,fmt.Println(utf8.RuneCountInString(s))
iota
包级别的函数:大写开头
可变参数:
函数返回参数:
闭包:
方法和函数是两个概念,但又非常相似,不同点在于方法必须要有一个接收者,这个接收者是一个类型,这样方法就和这个类型绑定在一起,称为这个类型的方法。
对象初始化:
如果要实现一个接口,必须实现这个接口提供的所有方法
以值类型接收者实现接口的时候,不管是类型本身,还是该类型的指针类型,都实现了该接口。
以指针类型接收者实现接口的时候,只有对应的指针类型才被认为实现了该接口。
如果重复了,应该还是A.B.C这样去取
在编程语言中,指针是一种数据类型,用来存储一个内存地址,该地址指向存储在该内存中的对象。这个对象可以是字符串、整数、函数或者你自定义的结构体。
指针变量的值就是它所指向数据的内存地址,普通变量的值就是我们具体存放的数据。
内置的 new 函数有一个参数,可以传递类型给它。它会返回对应的指针类型
虽然指向具体类型的指针可以实现一个接口
,但是指向接口的指针
永远不可能实现该接口。
那么为什么值类型在参数传递中无法修改呢?
Go 语言中的函数传参都是值传递。 值传递指的是传递原来数据的一份拷贝,而不是原来的数据本身
除了 struct 外,还有浮点型、整型、字符串、布尔、数组,这些都是值类型。
在 Go 语言中,任何创建 map 的代码(不管是字面量还是 make 函数)最终调用的都是 runtime.makemap 函数。
makemap 函数返回的是一个 *hmap 类型,也就是说返回的是一个指针,所以我们创建的 map 其实就是一个 *hmap。
因为 Go 语言的 map 类型本质上就是 *hmap,所以根据替换的原则,我刚刚定义的 modifyMap(p map) 函数其实就是 modifyMap(p *hmap)。这是不是和上一小节讲的指针类型的参数调用一样了?这也是通过 map 类型的参数可以修改原始数据的原因,因为它本质上就是个指针。
make 函数只用于 slice、chan 和 map 这三种内置类型的创建和初始化,因为这三种类型的结构比较复杂,比如 slice 要提前初始化好内部元素的类型,slice 的长度和容量等,这样才可以更好地使用它们。
在Go语言中,使用make
创建map与不使用make
创建map之间的区别主要体现在初始化和性能优化上。以下是这个领域最重要的20%的知识,以帮助你快速学习起80%:
使用make
创建map
-
初始化:使用
make
函数可以初始化map,使其不再是nil
,可以直接进行赋值操作。例如:m := make(map[string]int) m["key"] = 1
这种方式避免了
nil
map的陷阱。 -
性能优化:通过
make
函数创建map时,可以指定初始容量,这有助于减少map在运行时的扩容操作,从而提高效率。例如:m := make(map[string]int, 100) // 初始容量为100
这种方式可以优化性能。
-
代码简洁:使用
make
函数使得代码更加简洁易读。
不使用make
创建map
-
零值陷阱:如果直接声明一个map而不进行初始化,它将默认为
nil
。在这种情况下,尝试向map中添加键值对会导致运行时错误:var m map[string]int m["key"] = 1 // 这里会引发panic
运行上述代码会引发
panic
,因为m
是nil
,无法进行赋值操作。 -
必须初始化:为了避免运行时错误,必须使用
make
函数对map进行初始化。
通过掌握这些核心概念,你可以快速理解在Go语言中使用make
创建map与不使用make
创建map的区别。
在Go语言中,使用make
和new
创建map的区别主要体现在返回类型、初始化方式和适用场景上。以下是这个领域最重要的20%的知识,以帮助你快速学习起80%:
使用make
创建map
- 返回类型:
make
返回的是引用类型的实例,可以直接使用。 - 初始化:
make
会对引用类型进行初始化,创建的变量不是零值,而是根据类型进行初始化。 - 适用场景:
make
仅用于创建引用类型的变量,如切片、映射和通道。
使用new
创建map
- 返回类型:
new
返回的是指向值类型实例的指针。 - 初始化:
new
创建的变量是零值,需要进一步初始化才能使用。 - 适用场景:
new
用于创建任意类型的变量,但不适用于引用类型(如切片、映射和通道)
,只能用于值类型的创建。
区别总结
- 返回类型:
make
返回引用类型实例,new
返回指针。 - 初始化:
make
进行类型初始化,new
进行零值初始化。 - 内存分配:
make
分配并初始化内存,new
仅分配内存。
通过掌握这些核心概念,你可以快速理解在Go语言中使用make
和new
创建map的区别。