前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go通关14:参数传递中,值、引用及指针之间的区别!

Go通关14:参数传递中,值、引用及指针之间的区别!

作者头像
微客鸟窝
发布2021-08-18 15:21:48
1.4K0
发布2021-08-18 15:21:48
举报
文章被收录于专栏:Go语言指北

您诸位好啊,我是无尘。值、引用类型还一头雾水吗,今天我们好好唠唠它们之间的区别。

值类型、引用类型

1、在Go语言中,值类型和引用类型有以下特点: a、「值类型」:基本数据类型,int,float,bool,string,以及数组和struct 特点:变量直接存储值,内存通常在栈上分配,栈在函数调用完会被释放

b、「引用类型」:指针,slice,map,chan,interface等都是引用类型 特点:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配,通过GC回收。

  • 严格来说,Go 语言没有引用类型。
  • 但是我们可以把 map、chan、函数、接口、slice 切片, 称为引用类型,这样便于理解。
  • 指针类型也可以理解为是一种引用类型。

上面我们提到了堆、栈,这里简单介绍下

❝内存分配中的堆和栈:

  • (操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
  • (操作系统):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

值类型和指针类型参数示例:

代码语言:javascript
复制
package main

import "fmt"

func main() {
 name := "无尘"
 modify1(name)
 fmt.Println("name的值为:", name)
 modify2(&name)
 fmt.Println("name的值为:", name)
}

func modify1(name string) { //值类型
 name = "wucs"
} 
func modify2(name *string) { //指针类型
 *name = "wucs"
}
//运行结果:
//name的值为: 无尘
//name的值为: wucs

引用类型

「map」以map类型为参数示例:

代码语言:javascript
复制
package main

import "fmt"

func main() {
 m:=make(map[string]int)
 m["无尘"] = 18
 fmt.Println("无尘的年龄为",m["无尘"])
 modify(m)
 fmt.Println("无尘的年龄为",m["无尘"])
}
func modify(p map[string]int)  {
 p["无尘"] =20
}
//运行结果:
//无尘的年龄为 18
//无尘的年龄为 20
  • 我们看到,函数 modify 的参数类型为 map ,数据仍然修改成功了。
  • 其实,在创建 map 的时候,最终调用的是 runtime.makemap 函数,makemap 函数返回的是一个 *hmap 类型,也就是说返回的是一个指针,所以我们创建的 map 其实就是一个 *hmap。
  • 因为 map 本质上就是个指针,所以通过 map 类型的参数可以修改原始数据。
代码语言:javascript
复制
// makemap implements Go map creation for make(map[k]v, hint).
func makemap(t *maptype, hint int, h *hmap) *hmap{
  //省略无关代码
}

「chan」channel 本质上也是个指针,来看源码:

代码语言:javascript
复制
func makechan(t *chantype, size int64) *hchan {
    //省略无关代码
}

可以看到创建的 chan 其实是个 *hchan,所以它在参数传递中也和 map 一样。

类型的零值

  1. 在 Go 语言中,定义变量可以通过声明或者通过 makenew函数,区别是 make 和 new 函数属于显示声明并初始化。
  2. 如果我们声明的变量没有显示的声明初始化,那么该变量的默认值就是对于类型的零值。

类型

零值

数值类型(int、float等)

0

bool

false

string

""(空字符串)

struct

内部字段的零值

slice

nil

map

nil

指针

nil

函数

nil

chan

nil

interface

nil

❝在 Go 语言中,「函数的参数传递只有值传递」,而且传递的实参都是原始数据的一份拷贝。如果拷贝的内容是值类型的,那么在函数中就无法修改原始数据;如果拷贝的内容是指针(或者可以理解为引用类型 map、chan 等),那么就可以在函数中修改原始数据。 ❞


有什么问题,可以公众号内回复或加我微信交流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微客鸟窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 值类型、引用类型
    • 引用类型
    • 类型的零值
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档