Program Life
  • Introduction
  • Catalog
  • Part I - Language
    • 目录
    • Golang
      • go 知识点合辑
      • go mod 简介
      • recover & const 简述
      • 关于 nil 的一些事情
      • slice 底层结构
    • JS
      • js 零基础起步
    • Python
      • python 基础
  • Part II - Network
    • 目录
    • TCP与UDP 对比
    • http2
      • http/2.0 and http/2.0 in Go
    • Grpc
      • gRPC 客户端连接语义与API
      • gRPC over http/2
      • gRPC 的 go 拦截器
  • Part III - Database
    • 目录
    • 常见 DB 基础细节
    • High Performance Mysql, 3th Edition - 笔记
    • mysql 中的索引类型
    • 批量写入造成mysql访问慢问题追踪
  • Part Ⅳ - Devops
    • 目录
    • Docker
      • Docker 基础使用指南
    • Kubernetes
      • K8S网络之网络框架
      • K8S网络之service间通信
      • K8S网络之集群外访问service的方式
    • IPVS 在 k8s 中连接保持引发的问题
    • Linux 常用指令
    • Linux 内存缓慢增长问题
    • Linux 性能领域大师布伦丹·格雷格的工具图谱
  • Part Ⅴ - Bigdata
    • 目录
    • Machine Learn
      • PCA原理推导
  • Part Ⅵ - Algorithm
    • 目录
    • 常用算法列表
    • 分布式一致性协议简介
    • ARC 算法简述
  • Part Ⅶ - Design
    • 目录
  • Part Ⅷ - Skill
    • 目录
    • 关于沟通、交流
    • Google 技能评分卡
    • 架构之重构的12条军规
    • 驾考指南
    • 杂项
    • RNote
      • 代码重构培训(笔记)
      • 登高四书(笔记)
      • 番茄工作法图解(笔记)
Powered by GitBook
On this page
  • Summary
  • Defination
  • nil切片 和 空切片

Was this helpful?

  1. Part I - Language
  2. Golang

slice 底层结构

slice 的底层结构,了解 slice 的实现基础

Summary

Go 中数组赋值和函数传参都是值复制的, 切片是引用传递

  • 数组

    • 初始化时指定长度,如:

        a := [2]int{1,2}
        var b [2]int
  • 切片(slice)

    • 是对数组一个连续片段的引用,所以切片是一个引用类型 (因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型)

    • 初始化时不指定长度,如:

        a := []int{1,2}
        var b []int

Defination

Slice 的数据结构定义如下:

    // runtime/slice.go
    type slice struct {
        array unsafe.Pointer
        len   int
        cap   int
    }

如果想从 slice 中得到一块内存地址,可以这样做:

    s := make([]byte, 10)defination
    ptr := unsafe.Pointer(&s[0])

如果反过来呢?从 Go 的内存地址中构造一个 slice。

    var ptr unsafe.Pointer
    var tmp = struct {
        addr uintptr
        len int
        cap int
    }{ptr, length, length}
    s := *(*[]byte)(unsafe.Pointer(&tmp))

构造一个虚拟的结构体,把 slice 的数据结构拼出来。

当然还有更加直接的方法,在 Go 的反射中就存在一个与之对应的数据结构 SliceHeader,我们可以用它来构造一个 slice

    var o []byte
    sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&o)))
    sliceHeader.Cap = length
    sliceHeader.Len = length
    sliceHeader.Data = uintptr(ptr)

nil切片 和 空切片

nil切片

    // 内存布局:
    //    Slice ---> nil | Len = 0 | Cap = 0
    var slice []int

空切片

    // 内存布局:
    //     Slice ---> Pointer to Array | Len = 0 | Cap = 0
    silce := make( []int , 0 )
    slice := []int{ }
Previous关于 nil 的一些事情NextJS

Last updated 5 years ago

Was this helpful?