书接上篇,我们了解了Go语言的指针类型,现在介绍Go语言的数据初始化。主要如下:
3.9 数据初始化这里的数据的初始化是指对某个数据类型的值或变量的初始化。在Go语言中,几乎所有的数据类型的值都可以使用字面量来进行表示和初始化。在大多数情况下,使用字面量就可以满足初始化值或变量的要求。
Go语言还提供了两个专门用于数据初始化的内建函数 new 和 make。
3.9.1 new内建函数 new 用于为值分配内存。它并不会去初始化分配到的内存,而只会清零它。例如:
new(T)
如上调用该表达式求值时,所做的是为 T 类型的新值分配并清零一块内存空间,然后将这块内存空间的地址作为结果返回。而这个结果就是指向这个新的 T 类型值的指针值。它的类型为 *T。new 函数返回的 *T 类型值总是指向一个 T 类型的零值。例如:
new(string)//求值结果指向的是一个string类型的零值""new([3]int)//求值结果指向的是一个[3]int类型的零值[3]int{0,0,0}
以标准库代码包 bytes 中的结构体类型 Buffer 为例, bytes.Buffer 是一个尺寸可变的字节缓冲区。它的零值就是一个立即可用的空缓冲区。例如:
// 求值结果就是一个指向一个空缓冲区的指针值,可以立即在这个缓冲区上进行读写 *** 作new(bytes.Buffer)
标准库代码包 sync 中的结构体类型 Mutex 也是一个可以 new 后即用的数据类型。它的零值就是一个处于未锁定状态的互斥量。
3.9.2 make内建函数 make 只能被用于创建切片函数、字典类型和通道类型的值,并返回一个已被初始化的(即非零值的)的对应类型的值。以上3个复合类型的特殊结构都是引用类型,在它们的每一个值的内部都会保持着一个对某个底层数据结构值的引用。如果不对它们的值进行初始化,那么其中的这种引用关系是不会建立起来的,同时相关的内部值也会不正确。因此在创建这3个引用类型的值的时候,必须将内存空间分配和数据初始化这两个步骤绑定在一起。
内建函数 make 除了会接受一个表示目标类型的类型字面量之外,还会接受一个或两个额外的参数。
对于切片类型来说,可以把新值的长度和容量也传递给 make 函数,例如:
make([]int, 10, 100)
如上创建了一个新的 [ ]int 类型的值,这个值的长度为 10,容量为 100。如果省略最后一个参数,即不指定新值的容量。这样的话,该值的容量会与其长度一致。例如:
s := make{[]int, 10}
变量 s 的类型是 [ ]int 的,而长度和容量都是 10。
在使用 make 函数初始化一个切片值的过程中,该值会引用一个长度与其容量相同且元素类型与其元素类型一致的数组值。这个数组值就是该切片值的底层数组。该数组值中每个元素都是当前元素类型的零值。但是,切片值只会展现出数量与其长度相同的元素。因此 make([ ]int, 10, 100) 所创建并初始化的值就是 [ ]int{0,0,0,0,0,0,0,0}。
在使用 make 函数创建字典类型的值的时候,也可以指定其底层数据结果的长度。但是,该字典值只会展示出我们明确“放入”的键值对。例如:
make(map[string]int, 100)
它所创建和初始化的值会使 map[string]int{}。虽然可以忽略那个用于表示底层数据结构长度的参数,但是这边还是建议:应该在性能敏感的应用场景下,根据这个字典值可能包含的键值对的数量以及“放入”它们的时间,仔细地设置该长度参数。
对于通道类型的值的数据初始化,这里可以使用 make 函数创建一个通道类型的值:
make(chan int, 10)
其中的第一个参数表示的是通道的类型,而第二个参数则表示该通道的长度。与字典类型相同,第二个参数也可以被忽略掉。对于忽略它的含义,在之后的博文中详细讲解通道类型的时候大家可以了解。
内建函数 make 只能被应用在引用类型的值的创建上。并且,它的结果是第一个参数所代表的类型的值,而不是指向这个值的指针值。如果想要获取该指针值的话,只需要如下:
m := make(map[string]int , 100)mp := &m
对于数据初始化需要考虑的一些规则:
字面量可以被用于初始化几乎所有的Go语言数据类型的值,除了接口类型和通道类型。接口类型没有值,而通道类型的值只能使用 make 函数来创建。如果需要指向值的指针值,可以在表示该值的字面量之上进行取址 *** 作。
内建函数 new 主要用于创建值类型的值。调用 new 函数的额表达式的结果值将会是指向被创建值的指针值,并且被创建值会是其所属数据类型的零值。因此,new 函数不适合被用来创建引用类型的值。其直接的原因是引用类型的值的零值都是 nil,是不可用的。
内建函数 make 仅被用于某些引用类型(切片类型、字典类型和通道类型)的指的创建。它在创建值之后还会对其进行必要的初始化。与 new 函数不同,调用 make 函数的表达式的结果值将会是被创建的值本身,而不是指向它的指针值。
结语Go数据类型的知识就记到这,下一篇介绍 Go语言数据的使用。其中 通道类型,比较特殊,将会在后续的博文仔细讲解,敬请期待…
最后附上知名的Go语言开源框架(每篇更新一个):
总结Skynet: 一个分布式服务框架。它可以帮助我们构建起大规模的分布式应用系统。它的源码放置在https://github.com/skynetservices/skynet上。
以上是内存溢出为你收集整理的Go语言学习11-数据初始化全部内容,希望文章能够帮你解决Go语言学习11-数据初始化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)