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语言高效I/O并发处理双缓冲和Exchanger模式实例探索

    Go语言高效I/O并发处理双缓冲和Exchanger模式实例探索

    这篇文章主要介绍了Go语言高效I/O并发处理双缓冲和Exchanger模式实例探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Go语言使用Buffer实现高性能处理字节和字符

    Go语言使用Buffer实现高性能处理字节和字符

    在 Go 中,bytes.Buffer 是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和字符,有需要的小伙伴可以了解下
    2025-01-01
  • 详解Go中Set的实现方式

    详解Go中Set的实现方式

    这篇文章主要介绍了详解Go中Set的实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • jenkins配置golang 代码工程自动发布的实现方法

    jenkins配置golang 代码工程自动发布的实现方法

    这篇文章主要介绍了jenkins配置golang 代码工程自动发布,jks是个很好的工具,使用方法也很多,我只用了它简单的功能,对jenkins配置golang相关知识感兴趣的朋友一起看看吧
    2022-07-07
  • Go语言实现Snowflake雪花算法

    Go语言实现Snowflake雪花算法

    雪花算法产生的背景当然是twitter高并发环境下对唯一ID生成的需求,得益于twitter内部牛的技术,雪花算法能够流传于至今并且被广泛使用,本文就详细的介绍一下,感兴趣的可以了解一下
    2021-06-06
  • 通过Golang编写一个AES加密解密工具

    通过Golang编写一个AES加密解密工具

    这篇文章主要为大家详细介绍了如何利用Golang制作一个AES加密解密工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-05-05
  • golang整合日志zap的实现示例

    golang整合日志zap的实现示例

    Go语言中的zap库提供了强大的日志管理功能,支持日志记录到文件、日志切割、多日志级别、结构化日志输出等,它通过三种方法zap.NewProduction()、zap.NewDevelopment()和zap.NewExample(),快速构建适用于不同环境的logger,感兴趣的可以了解一下
    2024-10-10
  • 使用Go语言编写一个NTP服务器的流程步骤

    使用Go语言编写一个NTP服务器的流程步骤

    NTP服务器【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议,为了确保封闭局域网内多个服务器的时间同步,我们计划部署一个网络时间同步服务器(NTP服务器),本文给大家介绍了使用Go语言编写一个NTP服务器的流程步骤,需要的朋友可以参考下
    2024-11-11
  • golang使用go test输出单元测试覆盖率的方式

    golang使用go test输出单元测试覆盖率的方式

    单元测试覆盖率是衡量代码质量的一个重要指标,重要的代码文件覆盖率应该至少达到80%以上,Java 可以通过JaCoCo 统计覆盖率,那么go 项目如何进行代码覆盖率测试呢,本文将给大家详细的介绍一下golang使用go test输出单元测试覆盖率的方式,需要的朋友可以参考下
    2024-02-02
  • Go中crypto/rsa库的高效使用指南

    Go中crypto/rsa库的高效使用指南

    本文主要介绍了Go中crypto/rsa库的高效使用指南,从 RSA 的基本原理到 crypto/rsa 库的实际应用,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02

最新评论