教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go语言值、指针和引用类型

go语言值、指针和引用类型

发布时间:2022-01-24   编辑:jiaochengji.com
教程集为您提供go语言值、指针和引用类型等资源,欢迎您收藏本站,我们将为您提供最新的go语言值、指针和引用类型资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>

Go语言的指针与C和C 中的指针类似,无论是语法上还是语意上。但是Go语言的指针不支持指针运算,这样就消除了在C和C 程序中一类潜在的bug。Go语言也不用free()函数或者delete操作符,因为Go语言有垃圾回收器,并且自动管理内存。Go语言引用类型的值以一种独特而简单的方式创建,并且一旦创建后就可以像Java或者Python中的对象引用一样使用。Go语言的值的工作方式与其他大多数主流语言一致。

<ul><li>关于值、指针和引用类型个人见解
以下仅代表个人观点,首先来说说值:对于值来说,我认为通常就是字面量,通常情况下 Go语言的变量持有相应的值。<code>y := 1.5</code>,我们认为y的值是<code>1.5</code>,这就是值。值在传递给函数或方法的时候会被复制一次,这对于布尔变量或者数值类型来说是非常廉价的,因为每个这样的变量只占1~8个字节。按值传递字符串也非常廉价,因为Go语言中的字符串是不可变的,Go语言编译器会将传递过程进行安全的优化,因此无论传递的字符串长度多少,实际传递的数据量都会非常小。(每个字符串的代价在64位的机器上大概是16字节,在32位的机器上大概是8字节[2]。)当然,如果修改了一个传入的字符串(例如,使用 = 操作符),Go语言必须创建一个新的字符串,并且复制原始的字符串并将其加到该字符串之后,这对于大字符串来说很可能代价非常大。</li></ul><pre><code class="lang-go hljs">y <span class="token operator">:=</span> <span class="token number">1.5</span> y<span class="token operator"> </span> z <span class="token operator">:=</span> math<span class="token punctuation">.</span><span class="token function">Ceil</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> </code></pre>

我们来看一下y的值传递过程

<table><thead><tr><th>语句</th><th>变量</th><th>值</th><th>类型</th><th>内存地址</th></tr></thead><tbody><tr><td>y := 1.5</td><td>y</td><td>1.5</td><td>float64</td><td>0xf000000001</td></tr><tr><td>y </td><td>y</td><td>2.5</td><td>float64</td><td>0xf000000001</td></tr></tbody></table><table><tbody><tr><td rowspan="3">z := math.Ceil(y)</td><td>y</td><td>2.5</td><td>float64</td><td>0xf000000001</td></tr><tr><td>x</td><td>2.5</td><td>float64</td><td>y的副本</td></tr><tr><td>z </td><td>3.0 </td><td>float64 </td><td>0xf000000023 </td></tr></tbody></table> 从概念上讲,变量是赋给一内存块的名字,该内存块用于保存特定的数据类型。因此如果我们进行一个短声明y := 1.5,Go语言就会分配一个足够放置一个float64数的内存块(8个字节)并将数字1.5保存到该内存块中。之后只要y还保存在作用域中,Go语言就会将变量y等同于这个内存块。因此如果我们在声明语句后面跟上一条y 语句,Go语言将修改变量y对应的内存块中保存的数值。然而如果我们将y传递给一个函数或者方法,Go语言就会传递一个y的副本。从另一方面来讲,Go语言会创建另一个与所调用的函数的参数名相关联的变量,并将y的值复制到为该新变量对应的新内存块中。

与C和C 不同,Go语言中的数组是按值传递的,因此传递一个大数组的代价非常大。幸运的是,在 Go语言中数组不常用到,因为我们可以使用切片来代替。我们将在下面章节讲解切片的用法。传递一个切片的成本与字符串差不多(在64位机器上为16字节,在32位机器上为12字节),无论该切片的长度或者容量是多大[3]。另外,修改切片也不会导致写时复制的负担,因为不同于字符串的是,切片是可变的(如果一个切片被修改,这些修改对于其他所有指向该切片的引用变量都是可见的)。

有时我们需要一个函数修改我们传入的值。由于值类型是复制的,因此任何修改只作用于其副本,而其原始值将保持不变。同时,传值的成本也可能非常高,因为它们会很大(例如,一个数组或者一个包含许多字段的结构体)。此外,本地变量在不再使用时会被垃圾回收(当它们不再被引用或者不在作用域范围时),然而在许多情况下我们希望自己来管理变量的生命周期而非由它们的作用域决定。
通过使用指针,我们可以让参数的传递成本最低并且内容可修改,而且还可以让变量的生命周期独立于作用域。指针是指保存了另一个变量内存地址的变量。创建的指针是用来指向另一个某种类型的变量,这样就保证了 Go语言知道该指针所指向的值占用多大的空间。我们马上会看到,一个被指针指向的变量可以通过该指针来修改。不管指针所指向值的大小,指针的传递是非常廉价的(64位的机器上占8字节,32位的机器上占4字节)。同时,对于某个指针所指向的变量,只要保证至少有一个指针指向该变量,该变量就会在内存中保存足够长的时间,因此它们的生命周期独立于我们所创建的作用域。

到此这篇关于“go语言值、指针和引用类型”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
指针和参数传递(Go语言)
Golang指针的使用限制和unsafe.Pointer的突破之路
Go语言的函数、方法和接口
golang静态代码检查_Golang面试题41道
golang 文件md5_Golang面试题41道
基于类型系统的面向对象编程语言Go
超详细的C 指针介绍及实例教程
Go语言发展历史、核心、特性及学习路线
go语言值、指针和引用类型
go语言杂谈-----函数返回局部变量问题(“逃逸分析”)

[关闭]
~ ~