美文网首页
白话go语言(一):slice的创建

白话go语言(一):slice的创建

作者: Top2_头秃 | 来源:发表于2019-05-11 22:12 被阅读0次

直奔主题,我们从源码分析开始,一步一步往下走,慢慢得到我们想知道的内容

slice的源码位于 runtime包的slice.go文件中,slice结构体

type slice struct {
      // go跟c一样是一个强类型的语言,这个unsafe.Pointer 可以看成是C中的(void*)
        // 一个(void)类型的指针array,指向了底层的数组结构
    array unsafe.Pointer 
    len   int // slice中元素的个数
    cap   int // 底层数组的容量大小
}

makeslice的源码

提前说一下 uintptr类型的含义,uintptr是指uinptr指针所指内容的大小。通俗的说就是如果指针指向的内容是char类型 uintptr就是一个字节,指向的是一个int类型 uintptr就是4个字节大小。
类似于c语言中的 int *a; sizeof(*a)


func makeslice(et *_type, len, cap int) unsafe.Pointer {
        // 计算要分配的堆内存的大小,并返回是否溢出。
        // 要分配的堆内存大小=实现slice要用到的底层数组大小cap*一个slice(中数据类型)的大小、
    mem, overflow := math.MulUintptr(et.size, uintptr(cap))
        // 如果内存溢出,活着要分配内存大于可分配的最大内存,或者slice元素个数比底层实现该slice结构的数组容量还要大
    if overflow || mem > maxAlloc || len < 0 || len > cap {
              /* 如果没有那么大的内存可分配 或者 cap<len,
那么就分陪len个元素的容量并看一下是否为超过可分配内存限制
*/
        mem, overflow := math.MulUintptr(et.size, uintptr(len))
        if overflow || mem > maxAlloc || len < 0 {
            panicmakeslicelen() // 抛出一个“len out of range”pannic
        }
        panicmakeslicecap() //抛出一个“cap out of range” panic
    }
        // 分配内存,这个函数太复杂了,我们暂时不分析
        // 返回锁分配的内存的收地址的指针
    return mallocgc(mem, et, true)
}
  • make()源码

该函数位于src/builtin 包中,由于go内联函数我们看不到函数的实现体,我也不知道为啥看不到,反正是听一位大佬说,内联函数无法看到实现体,可能是代码太烂了,不忍心让人看吧,谁也说不准 😄

func make(t Type, size ...IntegerType) Type

我们就只分析函数名称和返回类型吧。
这个函数提供了两个参数
t:Type类型(这里的Type只能是map slice 或者chan)
三个点表示可以有任意多个参数,这些参素的类型是IntegerType类型
返回类型就是t对应的类型。

-----------------------我是分割线------------------------

源码也看了,现在我们分析一下make一个slice的过程,同时意淫以下那个 因为代码太烂而不忍心让大家看到实现体的 make函数到底干了哪些见不得人的勾当。

创建一个slice var s []int = make([]int,5,10)

  1. 第一个参数t 是一个int类型的数组,那第二个和第三个又是什么意思呢。
  2. 我们猜测(其实就是)内敛函数make其实调用了makeslice,
    3.通过前面的makesslice源码分析,第二个参数5其实对应的slice结构体的len,第三个参数10对应的就是slice结构体的cap
    4 在make函数中 我们初始化了slice 结构体中的这两个值,同时makesslice返回的指针初始化了slice结构体的array

看到这里,大家应该也能明白为啥slice只能由make创建,因为只有make中能初始化slice结构体中的这两个变量😄

相关文章

  • 白话go语言(一):slice的创建

    直奔主题,我们从源码分析开始,一步一步往下走,慢慢得到我们想知道的内容 slice的源码位于 runtime包的s...

  • Go语言——Slice分析

    Go语言——Slice分析 源码很不好找,在go\src\runtime\slice.go。 根据容量cap*元素...

  • go 语言切片

    go 语言切片 简单切片 slice 是 对 array 的一个 view 创建简单切片 切片作为函数参数 对切...

  • Go-数组与slice

    本文将讲解Go语言中的数组与slice。之前看到网上好多 《深入理解slice》、《深入解析slice》... 的...

  • 七、Go切片

    七、Go语言切片(Slice) Go 语言切片是对数组的抽象。 Go 数组的长度不可改变,在特定场景中这样的集合就...

  • go语言slice数据类型的定义和使用

    这篇文章介绍go语言slice数据类型的定义,内部格式,以及如何声明和定义slice类型变量。 slice数据类型...

  • Go语言切片(Slice)

    Go 语言切片是对数组的抽象。 Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,...

  • Go slice那些事

    今晚闲来无事,总结一下Go的slice slice是什么slice在Go中的原型?slice类似数组,是一种定长的...

  • Go语言基础04-引用类型

    引用类型就是创建变量的时候,变量其实是一个指向内存的指针。 Go 语言官方说的引用类型有三个:slice切片、ma...

  • Golang Slice详解

    1、简介 Go的 Slice(切片)类型提供了一种方便有效的方法来处理类型化数据序列。 slice类似于其他语言中...

网友评论

      本文标题:白话go语言(一):slice的创建

      本文链接:https://www.haomeiwen.com/subject/pcgfaqtx.html