GoLang中按值传递的值

现在,我们进入了一些核心概念! 众所周知,了解Go程序对机器的影响非常重要。

无论您通过了什么,一切都在Go中通过价值传递。 你所看到的就是你得到的。

每个go例程(即执行路径)都将获得Stack,这是一个连续的内存。 Go例程需要堆栈来完成所需的所有分配。 稍后我们将学习go例程,它就像一个线程,但更轻巧。

当go例程执行一个函数时,它将开始从分配的堆栈中获取一部分或一部分内存。

让我们尝试通过一个简单的例子来理解这一点

func main() {

  counter := 0

  counter++
 fmt.Println("In main", counter)
 inc(counter)
 fmt.Println("After inc", counter)
}
GoLang的价值

函数只能对其堆栈帧进行读/写,这就是为什么需要函数参数的原因。

在上面的示例中,inc函数所做的任何更改都是该堆栈帧的本地内容,如果要与调用者共享,则必须将其返回,以便可以将值复制到调用者帧。

关于堆栈框架的其他有趣属性是,例如,在inc函数完成执行后,堆栈框架可用于其他功能,因此可重用。

因此,就像堆栈中的增量指针为功能分配内存一样,一旦该功能完成,就递减计数器以将内存标记为空闲。

为了安全起见,需要传递值,以推断出许多语言中缺少的代码。

让我们探索将变量的指针或地址传递给函数时的所有这些更改。

让我们尝试了解执行以下代码时堆栈帧的外观

func main() {

 counter := 0

 fmt.Println("Before pointer inc ", counter)
 incByPointer(&counter)
 fmt.Println("After pointer inc ", counter)
}
GoLang的价值

在上面的示例中,函数的参数仍按值传递,但是这次它是地址类型。

调用者知道它已接收到变量的地址(&variable),并且要更改其值,必须使用其他指令(* variable)

星号(*)运算符允许程序更改其自身堆栈框架之外的变量。 此变量可以在堆中或在调用程序函数堆栈中。

传递值与地址的地址之间有明显的区别是一项非常强大的功能,因为它可以告诉哪个函数正在执行读写操作。

每当您看到指针(&)时,很明显函数中正在发生某些突变。

不可能进行神奇的修改。

具有明显的区别有两个优点:

–编译器可以进行转义分析,以确定分配给堆栈还是堆的内容。 由于堆栈分配便宜且堆具有GC开销,这使GC保持快乐

–何时复制价值与股份价值。 对于较大的值,这是非常有用的事情,您不想复制1gb的缓冲区即可起作用。

Go lang为开发人员提供了选择权衡的选项,而不是没有控制权。

让我们再看一个有关分配如何工作的示例:

func allocateOnStack() stock {

 google := stock{symbol: "GOOG", price: 1109}
 return google
}

func allocateOnHeap() *stock {

 google := stock{symbol: "GOOG", price: 1109}
 return &google
}

上面的两个函数都在创建股票值,但查看返回类型:一个返回值(allocateOnStack),另一个返回值(allocateOnHeap)返回地址。

编译器查找返回类型并决定堆栈与堆之间的关系。

因此,您决定要在GC上投入多少,还是让它高兴。

您可能对堆栈有疑问,例如堆栈有多大?

每个Go例程都以2 MB的堆栈大小开始,它很小而且足够容纳很多函数调用。

在大多数情况下,2 MB是不错的选择,但是如果程序继续对Stack施加内存压力,则它会增长以仅调整对特定Go例程的需求。

堆栈增长具有分配和复制成本,就像分配新数组并从先前数组复制值一样。

关于堆栈内存的一件好事是,它由GC监视,并且如果堆栈利用率约为25%,它将减小堆栈的大小。

Go使用Struct提供紧凑的内存布局功能,并使用按值传递来进行有效的内存分配。

此博客中使用的所有示例均可用@ 指针 github回购

翻译自: https://www.javacodegeeks.com/2019/01/value-pass-value-golang.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值