go值赋值和引用赋值的使用

 更新时间:2023年10月31日 15:22:19   作者:liulanba  
本文将介绍Go语言中的值赋值和引用赋值,并比较它们之间的差异,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

值赋值(Value Assignment)

值赋值是指将一个变量的值复制给另一个变量。当进行值赋值时,会创建原始值的一个副本,并将副本赋值给目标变量。这意味着目标变量和源变量是完全独立的,它们引用的是不同的内存地址。修改目标变量的值不会影响源变量的值。

var a = 10
var b = a // 值赋值
b = 20
fmt.Println(a) // 输出: 10
fmt.Println(b) // 输出: 20

在上述代码中,将变量 a 的值赋值给变量 b,然后修改 b 的值不会影响到 a

引用赋值(Reference Assignment)

引用赋值是指将一个引用(指针、切片、映射、通道等)复制给另一个变量。当进行引用赋值时,目标变量和源变量引用的是相同的底层数据。它们指向同一块内存地址。因此,修改目标变量会影响源变量,因为它们共享相同的数据。

var slice1 = []int{1, 2, 3}
var slice2 = slice1 // 引用赋值
slice2[1] = 10
fmt.Println(slice1) // 输出: [1 10 3]
fmt.Println(slice2) // 输出: [1 10 3]

在上述代码中,将切片 slice1 的引用赋值给 slice2,然后修改 slice2 中的元素会影响到 slice1,因为它们引用的是同一块内存。
需要注意的是,值赋值和引用赋值的行为取决于变量的类型。对于基本类型(如整数、浮点数、布尔值等),进行值赋值时会复制值;对于引用类型(如切片、映射、通道等),进行引用赋值时会共享底层数据。

结构体的值赋值在 Go 语言中,结构体类型的赋值操作是进行值拷贝

package main

import "fmt"

type Person struct {
	Name string
	Age  int
}

func main() {
	p1 := Person{Name: "Alice", Age: 30}

	p2 := p1

	p3 := Person{Name: p1.Name, Age: p1.Age}

	p1.Age = 31

	fmt.Println(p2) // 输出: {Alice 30}
	fmt.Println(p3) // 输出: {Alice 30}
}

在执行 p2 := p1 时,会创建一个新的结构体变量 p2,并将 p1 的字段值逐个复制到 p2 中。

创建了一个新的结构体变量 p3,并将 p1 的字段值逐个复制给 p3。因此,p3 是一个独立的结构体变量,它和 p1 指向不同的内存空间。当对 p1 的字段进行修改时,p3 不会受到影响,因为它们引用的是不同的内存地址。

结构体的引用赋值结构体的引用赋值是指将一个结构体变量的引用(指针)赋值给另一个结构体变量。通过引用赋值,两个结构体变量将引用相同的底层数据。

引用赋值适用于结构体类型,包括自定义的结构体类型和内置的结构体类型(如切片、映射等)。

type Person struct {
    Name string
    Age  int
}

func main() {
    p1 := Person{Name: "Alice", Age: 30}

    // 引用赋值
    p2 := &p1

    p1.Age = 31

    fmt.Println(p1) // 输出: {Alice 31}
    fmt.Println(*p2) // 输出: {Alice 31}
}

在上述代码中,通过 p2 := &p1 将 p1 的指针赋值给了 p2,实现了引用赋值。p2 和 p1 都指向相同的结构体数据。

因此,当修改 p1 的字段值时,通过 p2 访问也会反映出修改的结果。这是因为 p2 和 p1 引用了同一块内存空间,它们共享相同的数据。

需要注意的是,引用赋值是一种浅拷贝操作。这意味着只有结构体本身被复制,而结构体内部的引用类型字段(如切片、映射等)不会被复制。修改引用类型字段时,会影响到所有引用该字段的结构体变量。

type Person struct {
    Name string
    Friends []string
}

func main() {
    p1 := Person{Name: "Alice", Friends: []string{"Bob", "Charlie"}}

    // 引用赋值
    p2 := &p1

    p1.Friends[0] = "David"

    fmt.Println(p1) // 输出: {Alice [David Charlie]}
    fmt.Println(*p2) // 输出: {Alice [David Charlie]}
}

在上述代码中,通过引用赋值将 p1 的指针赋值给了 p2。修改 p1 的 Friends 字段的元素时,通过 p2 访问也会反映出修改的结果。这是因为 p1 和 p2 共享同一个切片的引用,它们指向相同的底层数据。

切片的值赋值copy 是一个内置函数,用于将一个切片的元素复制到另一个切片中

package main

import "fmt"

func main() {
	ls := []int{2, 45, 4, 57}
	var lk = make([]int, 5)
	copy(lk, ls)
	lk[1] = 2222
	fmt.Println(ls, lk)
}

通过 copy 函数将 ls 的元素复制到 lk,并修改了 lk[1] 的值,这个修改只会影响到 lk 自身,不会影响 ls。因为 copy 函数会将源切片的元素值复制到目标切片中。在这个过程中,源切片和目标切片是完全独立的,它们分别引用不同的底层数组。修改目标切片 lk 中的元素值不会影响原始切片 ls,因为它们引用的是不同的内存空间。

到此这篇关于go值赋值和引用赋值的使用的文章就介绍到这了,更多相关go值赋值和引用赋值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go 语言爬虫库goquery的具体使用

    go 语言爬虫库goquery的具体使用

    GoQuery是专为Go语言设计的一个强大的HTML解析和查询库,本文主要介绍了go语言爬虫库goquery的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Go 切片导致内存泄露的几种原因

    Go 切片导致内存泄露的几种原因

    某些情况下,对一个已存在的切片或数组进行切分操作可能会导致内存泄漏,本文主要介绍了Go 切片导致内存泄露的几种原因,感兴趣的可以了解一下
    2023-05-05
  • Go语言Gin框架中使用MySQL数据库的三种方式

    Go语言Gin框架中使用MySQL数据库的三种方式

    本文主要介绍了Go语言Gin框架中使用MySQL数据库的三种方式,通过三种方式实现增删改查的操作,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Go 一般方法与接口方法接收者的差异详解

    Go 一般方法与接口方法接收者的差异详解

    这篇文章主要为大家介绍了Go 一般方法与接口方法接收者的差异详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Swaggo零基础入门教程

    Swaggo零基础入门教程

    swagger是一套基于OpenAPI规范构建的开源工具,使用RestApi。swagger-ui呈现出来的是一份可交互式的API文档,可以直接在文档页面尝试API的调用
    2023-01-01
  • 一文搞懂Go语言中文件的读写与创建

    一文搞懂Go语言中文件的读写与创建

    这篇文章主要为大家详细介绍了Go语言中文件是如何实现读写与创建的,文中的示例代码讲解详细,对我们学习Go语言有一定帮助,需要的可以参考一下
    2022-07-07
  • Go语言错误处理异常捕获+异常抛出

    Go语言错误处理异常捕获+异常抛出

    这篇文章主要介绍了Go语言错误处理异常捕获和异常抛出,Go语言的作者认为java等语言的错误处理底层实现较为复杂,就实现了函数可以返回错误类型以及简单的异常捕获,虽然简单但是也非常精妙,大大的提高了运行效率,下文需要的朋友可以参考一下
    2022-02-02
  • Golang实现Redis网络协议实例探究

    Golang实现Redis网络协议实例探究

    这篇文章主要为大家介绍了Golang实现Redis网络协议实例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Go实现一个配置包详解

    Go实现一个配置包详解

    在现代软件开发中,配置文件是不可或缺的一部分。在编写 Go 项目时,程序的灵活性和可扩展性都需要依赖于配置文件的加载。本文就来探究下在 Go 项目中如何更加方便的加载和管理配置,感兴趣的朋友跟着小编一起来学习吧
    2023-04-04
  • go语言返回1-99之间随机数的方法

    go语言返回1-99之间随机数的方法

    这篇文章主要介绍了go语言返回1-99之间随机数的方法,实例分析了Go语言中rand的使用技巧,需要的朋友可以参考下
    2015-03-03

最新评论