一文搞懂GO语言的数组、指针、切片、Buffer

目录

 

数组

指针

切片

切片扩展

切片收缩

Buffer

总结


数组

数组定义的格式:var 数组名 [长度]类型 

定义一个8字节长的byte数组:var bytes_array [8]byte

var bytes_array = [8]byte{1, 2, 3, 4, 5, 6, 7, 8}
fmt.Printf("bytes_array len:%d bytes_array[0]:%d\n", len(bytes_array), bytes_array[0])
bytes_array len:8 bytes_array[0]:1

一文搞懂GO语言的数组、指针、切片、Buffer_第1张图片

fmt.Println(bytes_array)
[1 2 3 4 5 6 7 8]

GO语言中的数组名代表整个数组的值,这点和C语言不一样,C语言的数组名是指向数组的指针。GO中数组类型是值类型,如果用数组做为函数参数,传递的是数组值的拷贝。

指针

前面说了数组是传值操作,用来在函数中传递效率明显不如指针,GO语言中数组名不能当做指针用,所以如果需要用数组的指针,需要定义一个专门的数组指针,然后将数组赋值给这个指针。

var bytes_array_point *[8]byte
bytes_array_point = &bytes_array
fmt.Println(bytes_array_point)
fmt.Printf("bytes_array_point[0]:%d\n", bytes_array_point[0])

&[1 2 3 4 5 6 7 8]
bytes_array_point[0]:1

用指针传递数值,拷贝的是指向数组的指针

一文搞懂GO语言的数组、指针、切片、Buffer_第2张图片

切片

数组定义的格式:var 数组名 []类型 

切片和数组区别就是定义时不指定长度, 切片有点类似指针,它本身不包含数据空间,len(bytes_slice)值是0

var bytes_slice []byte
fmt.Printf("bytes_slice len %d\n", len(bytes_slice))

bytes_slice len 0

将数组赋值给切片

bytes_slice = bytes_array[:]
fmt.Printf("bytes_slice[0] %d len %d\n", bytes_slice[0], len(bytes_slice))

bytes_slice[0] 1 len 8

实际使用的时候一般用make直接给切片申请空间

这里的32是cap值,表示底层申请的空间;8是len值,表示当前切片使用的长度。

bytes_slice:= make([]byte, 8, 32)

如果不指定cap值,默认cap值等于len,下面的定义cap=8.

bytes_slice:= make([]byte, 8) 

切片扩展

切片不同于数组,它的长度可以变化。

假设原来的切片bytes_slice长度len=8,cap=8

[1 2 3 4 5 6 7 8] 

我们需要扩展一个数值9

bytes_slice = append(bytes_slice, 9)

[1 2 3 4 5 6 7 8 9] 

扩展后bytes_slice的len=9,cap=16(调用append扩展后,如果len长度没有超过cap,那只增加len长度,如果len超过cap了,那cap会扩展到原来的一倍长,比如原来cap=8, append扩展后cap=16)

切片收缩

在一个集合里面指定其子集合就能达到收缩的目的

bytes_slice = bytes_array[0:4]

一文搞懂GO语言的数组、指针、切片、Buffer_第3张图片

Buffer

Buffer是bytes包中封装的对象,Buffer是一个长度可变的带读写方法的字节缓存,它提供了一些常用的方法,比如Read、Write、WriteString

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
	buf      []byte // contents are the bytes buf[off : len(buf)]
	off      int    // read at &buf[off], write at &buf[len(buf)]
	lastRead readOp // last read operation, so that Unread* can work correctly.

	// FIXME: it would be advisable to align Buffer to cachelines to avoid false
	// sharing.
}

 buf:byte类型的切片;off:指向读的位置;len(buf)指向写的位置。

从上面的定义可以看到Buffer就是对切片的操作,它提供了操作bytes空间常用的操作,如Write,Read等操作,不需要我们自己去扩展空间

var bytes_buffer []byte
buffer := bytes.NewBuffer(bytes_buffer)
buffer.Write(data[0:4])

 

总结

数组的长度是固定的,切片的大小可以扩展,Buffer封装了切片提供了一些常用的方法,所以在项目中建议使用Buffer

 

 

你可能感兴趣的:(GO)