Golang指针详解

这篇具有很好参考价值的文章主要介绍了Golang指针详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

要搞明白Go语言中的指针需要先知道3个概念:指针地址、指针类型和指针取值。

指针介绍

我们知道变量是用来存储数据的,变量的本质是给存储数据的内存地址起了一个好记的别名。比如我们定义了一个变量 a := 10 ,这个时候可以直接通过 a 这个变量来读取内存中保存的 10 这个值。
在计算机底层 a 这个变量其实对应了一个内存地址。
指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另
一个变量的内存地址。
Golang指针详解,# Golang,golang,开发语言,后端

 

Go语言中的函数传参都是值拷贝,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量。传递数据使用指针,而无须拷贝数据。类型指针不能进行偏移和运算。

Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)*(根据地址取值)

指针地址和指针类型

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。
Go 语言中使用&字符放在变量前面对变量进行取地址操作。
Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。
取变量指针的语法如下:
 ptr := &v    // v的类型为T
 v:代表被取地址的变量,类型为T
    ptr:用于接收地址的变量,ptr的类型就为*T,称做T的指针类型。*代表指针。

 

package main

import "fmt"

func main() {

	//在计算机底层 a 这个变量其实对应了一个内存地址
	var a int = 1
	fmt.Printf("a的值为%v a的类型为%T a的内存地址为%v\n",a,a,&a)
	
	// 指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址
	var b int = 10
	c := &b //c指针变量   c的类型 *int(指针类型)
	fmt.Printf("b的值为%v b的类型为%T b的内存地址为%v\n",b,b,&b)
	fmt.Printf("c的值 %v c的类型%T ", c, c)

	//每一个变量都有自己的内存地址
	var f int = 20
	d := &f
	fmt.Printf("f的值 %v f的类型%T f的地址%p\n", f, f, &f)
	fmt.Printf("d的值 %v d的类型%T d的地址%p", d, d, &d)
	



}

Golang指针详解,# Golang,golang,开发语言,后端

b := &a的图示: 

 指针取值

在对普通变量使用&操作符取地址后会获得这个变量的指针,然后可以对指针使用*操作,也就是指针取值,代码如下。

package main

import "fmt"

func main() {
	var e int = 30
	var d *int = &e
	// d := &e
	// *d :表示取出d这个变量对应的内存地址的值
	fmt.Println(d)
	fmt.Println(&e)
	fmt.Println(*d)  

	*d = 40			//改变d这个变量对应的内存地址的值(之前所赋的是e的内存地址的值)
	fmt.Println(e)
	

}

Golang指针详解,# Golang,golang,开发语言,后端

总结: 取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址
指向的值。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

   1.对变量进行取地址(&)操作,可以获得这个变量的指针变量。
    2.指针变量的值是指针地址。
    3.对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。

指针传值示例

package main

import "fmt"

func fn1(x int) {
	x = 10
	// fmt.Println(x)
}

func fn2(x *int) {
	*x = 40
	// fmt.Println(*x)
}

func main() {
	var a = 5
	fn1(a)
	fmt.Println(a) //5;方法内的值并未改变a的内存地址,其原本的值所以没有变化
	fn2(&a)
	fmt.Println(a) //40 ;方法内传入的是指针类型,传入a改变了指针对应的内存地址,导致取指针的值变化了

}

Golang指针详解,# Golang,golang,开发语言,后端

 new和make

在 Go 语言中 对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间 ,否
则我们的值就没办法存储。(触发panic)
而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已
经默认分配好了内存空间。要分配内存,就引出来今天的 new 和 make。
Go 语言中 new 和 make 是内建的两个函数,主要用来分配内存。

make

make也是用于内存分配的,区别于new,它只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。make函数的函数签名如下:

func make(t Type, size ...IntegerType) Type

make函数是无可替代的,我们在使用slice、map以及channel的时候,都需要使用make进行初始化,然后才可以对它们进行操作。

 

package main

import "fmt"

func main() {


	// var teseDemo map[string]string  错误
	// teseDemo["卫宫士郎"] = "sabar"
	// fmt.Println(teseDemo)

	var teseDemo = make(map[string]string)
	teseDemo["远坂应"] = "archer"
	fmt.Println(teseDemo)

	var demo []int
	demo = append(demo,1 ) // qppend是可以实现的,但是如果是直接demo[0] = 1
	fmt.Println(demo[0])

	// var demo1 []int
	// demo1[0] = 2 // 如果是直接demo[0] = 1,会因为没有分配内存而panic
	// fmt.Println(demo[0])

	var demo1 = make([]int, 4,4)
	demo1[1] = 12
	fmt.Print(demo1)

	//指针也是引用数据类型 不分配内存空间也会报错  错误
	// var a *int 
	// *a = 100
	// fmt.Println(*a)
}

Golang指针详解,# Golang,golang,开发语言,后端

new

new是一个内置的函数,它的函数签名如下:

    func new(Type) *Type

其中,

    1.Type表示类型,new函数只接受一个参数,这个参数是一个类型
    2.*Type表示类型指针,new函数返回一个指向该类型内存地址的指针。

new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。举个例子:

	var a *int
	a = new(int)
	*a = 10
	fmt.Println(*a) //0

	var b = new(bool)
	fmt.Println(*b) //false

Golang指针详解,# Golang,golang,开发语言,后端

package main

import "fmt"

func main() {
		a := new(int)
		b := new(bool)
		fmt.Printf("%T\n", a) // *int
		fmt.Printf("%T\n", b) // *bool
		fmt.Println(*a)       // 0
		fmt.Println(*b)       // false
}

 Golang指针详解,# Golang,golang,开发语言,后端文章来源地址https://www.toymoban.com/news/detail-607440.html

new与make的区别 

   1.二者都是用来做内存分配的。
    2.make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身;
    3.而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针。

到了这里,关于Golang指针详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • golang学习-指针

    1、定义 指针也是一个变量,但它是一个特殊的变量,它存储的是另一个变量的内存地址。是引用数据类型。 取一个变量的地址:a  定义: var p *int = a 可以理解为 指针变量p中存储的是a的内存地址,但是变量p也有自己的内存地址。 2、指针取值 *p 表示的是 取出p这个变量对

    2024年02月02日
    浏览(34)
  • GoLang 中*(指针)与&(地址)的详细学习

    Go语言提供了控制数据结构指针的能力,但是不能进行指针运算。Go语言允许你控制特定集合的数据结构、分配的数量以及内存访问模式。指针对于性能的影响相信程序员都知道。 类型指针 允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,无须拷贝数据,此

    2024年02月16日
    浏览(40)
  • 【后端学习笔记·Golang】邮箱邮件验证

    流程: 接收用户请求后生成随机验证码,并将验证码存入Redis中,并设置TTL 通过gomail发送验证码给用户邮箱 接收用户输入的验证码,与Redis中存放的验证码进行比对 ​ 随机种子通过 time.Now().UnixNano() 进行设置,以确保对于同一个用户每次请求都使用不同的种子。然后,定义

    2024年04月26日
    浏览(50)
  • 【Java|golang】143. 重排链表---快慢指针

    给定一个单链表 L 的头节点 head ,单链表 L 表示为: L0 → L1 → … → Ln - 1 → Ln 请将其重新排列后变为: L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → … 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例 1: 输入:head = [1,2,3,4] 输出:[1,4,2,3] 示例 2: 输入:

    2024年02月14日
    浏览(32)
  • golang iris框架 + linux后端运行

    打包应用 开启服务 关闭后台 杀死进程 通过 ps -ef|grep main 找到应用出现 找到应用的( PID(一般是第一个数字) )

    2024年02月07日
    浏览(54)
  • Golang struct 结构体指针类型 / 结构体值类型

    结构体变量之间的赋值是值拷贝。 当需要通过变量去修改另外一个结构体内容的时候,可以通过传递地址的方式来达到这个效果。 这样使用肯定是不对的,因为.的运算优先级要高,所以先会去执行p2.age,之后又取地址,所以这个就不行。 在代码执行的时候先执行.的操作,

    2024年02月13日
    浏览(42)
  • Golang对比Java、python为什么要保留指针

    平时我们在Golang使用指针一般是为了以下的情况: 方法直接修改原来对象 保证参数传递的自由,可以在传递重量级对象时使用指针 但Go 保留指针不仅仅是为了解决传递参数的问题,还跟它的语言特性有密不可分的联系。 Go 里面的变量是 值语义 ,这个跟 C/C++是一脉相承的。

    2024年01月17日
    浏览(68)
  • golang中的指针方法和值方法的区别,编程时该如何选择呢?

    我们都知道,方法的接收者类型必须是某个自定义的数据类型,而且不能是接口类型或接口的指针类型。所谓的值方法,就是接收者类型是非指针的自定义数据类型的方法。 Choosing whether to use a value or pointer receiver on methods can be difficult, especially to new Go programmers. If in doubt, use

    2024年02月09日
    浏览(76)
  • 【Golang】Golang进阶系列教程--Go 语言 map 如何顺序读取?

    Go 语言中的 map 是一种非常强大的数据结构,它允许我们快速地存储和检索键值对。 然而,当我们遍历 map 时,会有一个有趣的现象,那就是输出的键值对顺序是不确定的。 先看一段代码示例: 当我们多执行几次这段代码时,就会发现,输出的顺序是不同的。 首先,Go 语言

    2024年02月14日
    浏览(65)
  • 【Golang】Golang进阶系列教程--Go 语言数组和切片的区别

    在 Go 语言中,数组和切片看起来很像,但其实它们又有很多的不同之处,这篇文章就来说说它们到底有哪些不同。 数组和切片是两个常用的数据结构。它们都可以用于存储一组相同类型的元素,但在底层实现和使用方式上存在一些重要的区别。 Go 中数组的长度是不可改变的

    2024年02月15日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包