Workspace
  • Introduction
  • Algorithm
    • 二叉树
    • 排序算法
  • Basic Knowledge
    • CAP定理
    • CAS-SSO-单点登陆
    • 单向认证-双向认证
  • CICD
  • Cloud Native
  • Docker
    • Docker特性
    • Docker资源隔离
  • Golang
    • Standard Library
      • Archive
        • Builtin
        • Zip
    • Golang-container包
    • Golang-fallthrough关键字
    • Golang For Slect
    • Golang-Goroutine泄露
    • Golang Interface
    • Golang-json.Unmarshal
    • Golang Label
    • Golang Map String Struct
    • Golang Map To Struct
    • Golang Override Package Function
    • Golang-Slice删除元素
    • Golang Switch
    • Golang-sync.Cond
    • Golang-sync.Map
    • Golang-sync.once
    • Golang-type关键字
    • Golang-代码生成
    • golang-并发数控制
    • Golang-并发退出
    • Golang-插件系统
    • Golang-继承
    • Golang之channel
    • Golang之continue
    • Golang之make与new和nil
    • Golang之map
    • Golang之reflect
    • Golang之类型判断
    • Golang代码质量检测
    • Golang变量避坑
    • Golang字符串遍历
    • golang并发控制代码示例
    • Golang性能优化
    • Golang死锁
    • goroutine-协程-线程-进程
    • go值传递
    • go内存逃逸分析
    • go并发MGP模式
    • go并发控制
    • 垃圾回收-三色法
  • Istio
    • 服务网格
  • Jenkins
    • Jenkin On K 8 S
    • Jenkins Mac
  • Kubernetes
    • Deployment
    • k8s容器内查看-cpu-memory分配情况
    • kube-proxy原理
    • Kubernetes Informers
    • Kubernetes扩展点
    • Kubernetes部署策略
    • Pod Non Root
    • Pod驱逐
    • PV PVC Storage Class
    • Security Context
    • 优雅热更新
  • Python
    • Python-vs-Golang协程区别
  • Serviceless
  • Shell
    • Shell小技巧
  • VPN
    • OC Serv
  • Redis
Powered by GitBook
On this page
  • 什么是值传递、传地址、传引用
  • Slice 类型陷井
  • map 传参
  • chan 传参
  • 总节
  • 参考

Was this helpful?

  1. Golang

go值传递

什么是值传递、传地址、传引用

任何一门语言在函数调用的时候,都有传参数的情况。都涉及传的是值,还是引用,或是指针。

  • 传值 其实就是实参拷贝传递给形参。简单来说就是把实参赋值给形参,赋值完毕后实参和形参就没有任何的关系了,对形参的修改不会影响到实参。

  • 传地址 传地址其实也是一种值传递,为什么这么说呢?因为传地址其实是把实参地址的拷贝传递给形参。简单来说,传地址就是把实参的地址复制给形参。复制完毕后实参的地址和形参的地址没有任何关系,对形参址址的更改不会影响到实参,但是对形参址址所指向的对象的更改却直接反应在实参中,因为形参指向的对象就是形参的对象。

  • 传引用 传引用本质没有任何实参的拷贝,简单来说,就是让另一个变量也执行该实参。就是两个变量指向同一个对象。这是对形参的修改,必然反映到实参上。

golang 来说是没有引用传递的,采用的是值传递,即使是指针,也是将指针的地址即指针的指针,拷贝一份传递。

Slice 类型陷井

golang 提供了 array 和 slice 两种序列结构。array 是值类型。slice 则是复合类型,slice 是基于 array 实现的。 当函数传 slice 的时候是值传递,通过原始变量进行切片传入。因为共同指向了 array,所以 函数内对 slice 进行修改可能也会对函数外的 array,slice 有影响。情况如下

  • 当在函数内执行 append 操作时,如果超过 slice 的容量,即数组的越界的时候,需要通过动态规划的方式创建了个新的数组块。把原有数据复制到新的数组,这个新的 array 则为 slice 新的底层依赖。

  • 当在函数执行任何操作时,没有超过 slice 容量,对 slice 的数据更新则会传递到函数外层。

当然如果传递的是指针,肯定也是会传递到函数外层的。

map 传参

make 函数返回的是一个 hmap 类型的指针 *hmap,所以传 map 可以直接修改其值。

chan 传参

chan 类型本质上和 map 类型是一个的,make 返回的是一个 *hchan 指针类型。

总节

golang 中所有的传参都是值传递(传值),都是一个副本,一个拷贝。非引用类型 int、string、struct 等,这样就在函数中无法修改原内容数据。引用类型 指针、map、slice、chan 等,这样就可以修改原内容数据。

是否可以修改原内容数据,和传值、传引用没有必然的关系。在C++中,传引用肯定是可以修改原内容数据的,在Go语言里,虽然只有传值,但是我们也可以修改原内容数据,因为参数是引用类型。

这里也要记住,引用类型和传引用是两个概念。

再记住,Go里只有传值(值传递)

参考

Previousgoroutine-协程-线程-进程Nextgo内存逃逸分析

Last updated 5 years ago

Was this helpful?

Golang切片与函数参数“陷阱”
技术周刊之golang中修改struct的slice的值
飞雪无情的博客