教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang-函数调用机制分析(值传递与引用传递)

Golang-函数调用机制分析(值传递与引用传递)

发布时间:2021-05-27   编辑:jiaochengji.com
教程集为您提供Golang-函数调用机制分析(值传递与引用传递)等资源,欢迎您收藏本站,我们将为您提供最新的Golang-函数调用机制分析(值传递与引用传递)资源

Golang-函数调用机制分析

  • 1. 值传递
  • 2. 引用传递
  • 3. 程序运行时的内存分析
    • 3.1 值传递内存分析
    • 3.2 引用传递内存分析
  • 4. 总结

1. 值传递

基本数据类型和数组作为参数会进行值传递

接下来看一个最简单的例子

import "fmt"

func test(num int) {
	num = num  1
	fmt.Println("test : ", num)
}

func main() {
	num := 10
	test(num)
	fmt.Println("main : ", num)
}

如果大家有其他语言的开发经验,应该很容易看出来程序的输出结果是

test : 11
main : 10

我们再来看看引用传递是什么结果

2. 引用传递

还是与上面的例子相同,只不过函数参数改为指针类型

import "fmt"

func test(ptr *int) {
	*ptr = *ptr  1
	fmt.Println("test : ", *ptr)
}

func main() {
	num := 10
	ptr := &num
	test(ptr)
	fmt.Println("main : ", num)
}

我们再来看一下输出结果

test : 11
main : 11

这两种不同的输出结果,底层到底是如何实现的呢,

3. 程序运行时的内存分析

对于程序而言,在运行是操作系统会为其分配一块内存,以满足程序的运行需要,程序的进程会将这块内存分为三个部分,分别是:1. 栈区 2. 堆区 3. 代码区。这是人为的逻辑上的划分。

后面会有专门的文章来做golang的GC分析以及涉及到的逃逸分析等

  • 栈区:一般来说存储基本数据类型
  • 堆区:一般来说存储引用数据类型
  • 代码区: 存储代码本身

3.1 值传递内存分析

下面我们就来对照一下代码与逻辑上的分区来看一下到底是什么输出结果

首先,代码从main函数开始执行,会在栈中开辟一块区域用来存储main函数的相关变量,注意这里只是人为的逻辑分区。此时就在main函数的栈区中开辟出一块空间用来存储变量num
此时程序运行到test函数处,此时在栈中开辟一块空间作为test函数的栈区,其中也会开辟一块空间存储一个num变量,只不过此时的test函数栈区中的nummain函数栈区中的num是两个变量,其中test函数栈去中的num的值为main函数栈区中num值的拷贝。

此时程序运行到test函数中,将test函数栈区中num 1操作,操作结束之后执行输出语句,输出的是test函数栈区中的num,故输出test : 11,之后程序返回到main函数中继续执行。

注意此时test函数已经执行完毕,所以将test函数的栈去已经自动从栈区中删除了,此时再执行输出语句,输出的是main函数栈区中保存的num,故输出num : 10

3.2 引用传递内存分析


与前面类似,也首先在栈去中开辟一块空间存储main函数的相关变量。

程序向下运行,此时会在堆区中分配一块空间,用来存放main函数的一些引用变量,其中的ptrint类型的指针,其值为main函数中num的地址,也就是ptr为指向num的指针。

函数执行到这里的时候,会在栈区和堆区也分别创建test函数的空间,其中在test函数堆中存储了一个ptr指针,其值为main函数堆中ptr值的拷贝,所以这两个ptr指针保存的都是main函数中num的地址,也就是说test函数堆区中的ptr指针也指向main函数栈区的num变量。

此时操作test堆区中的ptr指针,也就像相当于操作main函数中的num变量,将其执行 1操作,程序继续执行故输出为test : 11

程序继续执行到main函数中的输出语句,此时已将test栈区所占空间自动释放,test堆区由GC机制决定何时释放。main函数输出的值就是main : 11

4. 总结

以上就是值传递与引用传递的分析。注意其中的栈,堆等均为人为的逻辑分区,每个程序在运行过程中也未必会严格按照此进行内存的分配,这里是为了解释方便,后期在做GC等分析的时候也会有更详细的说明。

到此这篇关于“Golang-函数调用机制分析(值传递与引用传递)”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang语言基础教程:函数的参数
golang 函数传多个参数_Golang中的参数传递示例详解
Golang-函数调用机制分析(值传递与引用传递)
Go 语言函数
指针和固定大小缓冲区只能在不安全的上下文使用_「GCTT 出品」Go 语言机制之栈和指针...
Go 语言机制之栈和指针
指针和参数传递(Go语言)
Go 异常处理机制——defer, error, panic, recover
Golang 模板(text/template) (一)
提高php运行效率的50个实用技巧

[关闭]
~ ~