Go语言地址引用的问题解决
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1、channel</a></li><li><a href="#_label1">2、slice</a></li></ul></div><p class="maodian"><a name="_label0"></a></p><h2>1、channel</h2><p>先看以下代码:</p>
<div class="jb51code"><pre class="brush:go;">package main
import "fmt"
func main() {
ch1 := make(chan int, 3)
ch2 := ch1
ch1 <- 123
ch2 <- 456
fmt.Println(ch1, ch2) //输出地址是否一样?TODO:打印结果是?
fmt.Println(<-ch2, <-ch1) // ch2中的数据是:456; ch1中的数据是123;TODO:打印结果是?
}</pre></div>
<p>输出结果:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025112109250247.png" /></p>
<p>代码分析:</p>
<p>在以上代码中,新定义的变量ch2:=ch1 ;ch2是地址引用,<span><strong>ch1,ch2地址指向的是同一块数据</strong></span>,ch1、ch2都可以改变数据。</p>
<p class="maodian"><a name="_label1"></a></p><h2>2、slice</h2>
<p>看看以下代码:</p>
<div class="jb51code"><pre class="brush:go;">package main
import "fmt"
func main() {
s := make([]int, 3)
s1 := s
s2 := s
s = 123
s1 = 456
s2 = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}</pre></div>
<p>输出结果:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025112109250280.png" /></p>
<p>代码分析:起初,s,s1,s2都指向同一块数据。所以任意一个变量修改了该块数据,其他变量查到的都是修改之后的数据。</p>
<p>指向:</p>
<div class="jb51code"><pre class="brush:go;">s2 = append(s2, 123),会在末尾追加一个元素,由于现有s2的</pre></div>
<div class="jb51code"><pre class="brush:go;">cap(s)=3, len(s)=3;</pre></div>
<p><span><strong>在追加数据时,容量已经不够,会开辟新的内存,将现有数据s2拷贝,形成新的s2。当然在容量足够的情况下,不会开辟新的内存空间。</strong></span></p>
<p>再来看以下代码:(容量大于append的数据数量)</p>
<div class="jb51code"><pre class="brush:go;">package main
import "fmt"
func main() {
s := make([]int, 3,6)
s1 := s
s2 := s
s = 123
s1 = 456
s2 = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
s=888 // TODO:会修改s1、s2吗
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}</pre></div>
<p>输出效果:</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025112109250272.png" /></p>
<p>在以上代码中添加内容:</p>
<div class="jb51code"><pre class="brush:go;">package main
import "fmt"
func main() {
s := make([]int, 3,6)
s1 := s
s2 := s
s = 123
s1 = 456
s2 = 789
fmt.Println("原始切片:", s)
fmt.Println("赋值切片:", s1)
fmt.Println("赋值切片:", s2)
fmt.Println("切片的长度、容量为:", len(s), cap(s))
fmt.Printf("追加之前的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
fmt.Println("====执行append操作====")
s2 = append(s2, 123)
fmt.Printf("追加之后的地址:s:%p ;s1:%p; s2:%p\n",s,s1,s2)
s=888 // TODO:会修改s1、s2吗
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
fmt.Println("执行以下操作,输出结果又是什么呢?")
s = append(s, 666)
fmt.Println("原始切片s:", s)
fmt.Println("赋值切片s1:", s1)
fmt.Println("赋值切片s2:", s2)
}</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202511/2025112109250238.png" /></p>
<p><span>特别说明:Go语言为了节省内存空间,对于切片、map、channel、指针等地址引用的变量,会操作同一块地址对应的数据,在操作时也特别留意。</span></p>
頁:
[1]