1.slice是什么结构

声明出来的slice占用了3个byte(24bit)
分别存储了:

  • 数据存哪里
  • 存了多少
  • 可以存多少

image.png

1.1怎么声明一个slice

使用make声明一个slice

  • 5:可访问前5个
  • 8:可以使用8个位置存数据
    1. var ints []int make([]int,5,8)
    2. ints=append(ints,1)
    3. ints[0]=1
    image.png
    image.png
    image.png

2.make和new

make一个slice,直接说明了需要的长度,所以直接申请到了一个底层数组

new却不是
ps:=new([]string)
ps是一个地址

3.slice和数组

底层数组是一块连续的内存空间,创建出来以后长度就不能改变了

  • 不同slice可以指向同一个底层数组
  • slice指向的底层数组并不一定要从头开始

    4.扩容规则

    4.1聊聊不同类型占用多少内存

  • 看一下不同int类型在Go语言中所占的字节数 ```go

package main

import ( “fmt” “unsafe” )

func main() { var i1 int = 1 var i2 int8 = 2 var i3 int16 = 3 var i4 int32 = 4 var i5 int64 = 5 fmt.Println(unsafe.Sizeof(i1)) fmt.Println(unsafe.Sizeof(i2)) fmt.Println(unsafe.Sizeof(i3)) fmt.Println(unsafe.Sizeof(i4)) fmt.Println(unsafe.Sizeof(i5)) } //输出结果: 8 1 2 4 8

  1. - 不同长度的数组也是不同的类型,他们在内存中占据着不同的字节数
  2. ```go
  3. var n [5]int
  4. fmt.Printf("n 的类型 %T n2占中的字节数是 %d", n, unsafe.Sizeof(n))
  5. //output:
  6. //n 的类型 [5]int n2占中的字节数是 40

底层数组创建出来以后长度就不能改变了,如果不够用了就需要扩容

4.2数组长度不够了怎么办

开辟新的数组,那么要开辟多少呢(cap的大小)

  • 规则

image.png
数组的容量知道了,那么内存申请多少呢

  • 规则

预估容量(cap)×元素类型占用byte

4.3开辟的内存找谁去要

  • slice底层数组开辟申请的内存都是向Go自己的内存管理模块申请的
  • 内存管理模块向OS申请了一批可能用得上的内存

image.png

假设新的数组预估容量为5

int:58=40byte———————->申请到48byte的内存 string:516=80byte———————->申请到80byte的内存

  1. ints:=[]int{1,2} //cap=2
  2. ints=append(ints,3,4,5) //cap=5+1
  3. fmt.Println(cap(ints))
  4. //output:
  5. 6