【30天熟悉Go语言】6 Go 复杂数据类型之指针

这篇具有很好参考价值的文章主要介绍了【30天熟悉Go语言】6 Go 复杂数据类型之指针。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

【30天熟悉Go语言】6 Go 复杂数据类型之指针

Go系列文章:

  1. GO开篇:手握Java走进Golang的世界
  2. 2 Go开发环境搭建、Hello World程序运行
  3. 3 Go编程规约和API包
  4. 4 Go的变量、常量、运算符
  5. 5 Go 基本数据类型

Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html

二、数据类型总览

【30天熟悉Go语言】6 Go 复杂数据类型之指针

三、指针

和 C/C++ 中的指针不同,Go中的指针不能进行偏移和运算。它是一种类型指针,可以用于传递数据、对数据进行修改。

简单一点理解:一个指针类型的变量其实就是一个值的内存地址,我们可以通过这个变量的地址(指针)去访问 / 操作数据。

使用指针获取变量内存地址的语法格式:

ptr := &v
  • v 是被取内存地址的变量;
  • 变量ptr的类型为*T,即T的指针类型,*代表指针;变量ptr用于接收变量v的内存地址。
  • 基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型
    • 比如:int的对应的指针为*intfloat32对应的指针类型为*float32,依次类推…

1、特殊运算符& *

在Go中 & 和 * 有特殊的用意:

  • & :返回变量的存储地址
  • *:指针取值,取指针变量对应的数值
func main() {
	var age int = 18
	fmt.Println("age对应的存储空间内存地址为:",&age)

	// 指针变量 ptr,指向age在存储空间的内存地址
	var ptr *int = &age
	// 指针变量的类型
	fmt.Printf("ptr类型为: %T\n", ptr)
	// ptr指向的内存地址
	fmt.Printf("ptr指向的内存地址为:%p\n", ptr)

	// ptr变量自身的内存地址
	fmt.Println("ptr变量自身存储的内存地址为:", &ptr)

	// 指针取值
	value := *ptr
	fmt.Println("ptr这个指针指向的具体数值为:", value)

	// 取值后的类型
	fmt.Printf("value type: %T \n", value)
}

控制台输出如下:
【30天熟悉Go语言】6 Go 复杂数据类型之指针

  • 变量ptr的类型为*int
  • ptr指针变量的值为指针地址(16进制的整数);
  • ptr的指针地址,为变量age的内存地址(0xc0000a6058);
  • ptr变量本身也需要一个内存地址(0xc0000ca020)进行存储
  • ptr变量的指针取值操作,获取到的值和类型为变量age的值和类型。

2、内存角度来看指针

普通变量:
【30天熟悉Go语言】6 Go 复杂数据类型之指针

使用var age int = 18声明一个age变量之后,实际在内存中为age变量开辟了一块空间,并且这个空间中存储的数值时18,内存空间会有一个唯一标识(内存地址)。

指针变量:

// 指针变量 ptr,指向age在存储空间的内存地址
var ptr *int = &age

// ptr指向的内存地址
fmt.Printf("ptr指向的内存地址为:%p\n", ptr)

// ptr变量自身的内存地址
fmt.Println("ptr变量自身存储的内存地址为:", &ptr)

【30天熟悉Go语言】6 Go 复杂数据类型之指针

使用var ptr *int = &age声明一个ptr指针变量之后,实际在内存中也为ptr变量开辟了一块空间,并且这个空间中存储的数值为age变量的内存地址(0xc0000a6058);ptr变临港在内存空间也会有一个唯一标识(内存地址:0xc0000ca020)。

3、使用指针修改数据

指针不只可以用来取值,也可以使用来修改值

var num int = 10
fmt.Println(num)
var ptr *int = &num
*ptr = 20
fmt.Println(num)

控制台输出:
【30天熟悉Go语言】6 Go 复杂数据类型之指针

上面介绍了*ptr为指针取值,这里呢,*ptr = ?则直接用于指针赋值,即修改指针地址的数据内容。

4、指针使用的注意事项

1> 指针变量接收的一定是地址值

// 这种方式不允许
var prt *int = num

2> 指针变量类型和相应数据的类型不可以不匹配

var num int = 10
fmt.Println(num)
// 这种方式不允许,ptr指针的类型应该为*int
var ptr *float32 = &num

解释:*float32 意味着指针指向的是float32类型的数据,但是&num对应的是int类型的数据,所以不可以这样操作。

5、对比着看Java的引用类型

Java也是按值传递,但针对引用类型,方法之间传递引用类型的变量实际传递的是变量的内存地址,通过这个变量我们可以直接操作相应类型在内存中的数据;

以下面的代码为例,在method b中修改了变量variable 的某一块数据,在method b 的上层方法method a中也是有感知的,因为它们共享同一块内存地址的数据。

public class Main {
    public static void main(String[] args) {
        a();
    }


    public static void a() {
        ClassA variable = new ClassA(18, "saint");
        System.out.println("进入method b 方法前:" + variable.toString());
        System.out.println("method a 中variable内存地址为:" + variable.hashCode());
        b(variable);
        System.out.println("进入method b 方法后:" + variable.toString());
    }

    public static void b(ClassA variable) {
        System.out.println("method b 中variable内存地址为:" + variable.hashCode());
        variable.setAge(28);
    }

    @Data
    @ToString
    static class ClassA {
        private Integer age;
        private String name;

        public ClassA() {
        }

        public ClassA(Integer age, String name) {
            this.age = age;
            this.name = name;
        }
    }
}

控制台输出:
【30天熟悉Go语言】6 Go 复杂数据类型之指针

如果在method b 中对变量variable进行了整体的重新赋值,则变量variable在method b中内存地址发生改变,与method b 上层方法method a中的内存地址不同了。即:它们不在共享同一块内存地址的数据,在method b中修改variable内部的值不会影响method a中的variable变量的数据。

public static void b(ClassA variable) {
    variable = new ClassA();
    System.out.println("method b 中variable内存地址为:" + variable.hashCode());
    variable.setAge(28);
}

【30天熟悉Go语言】6 Go 复杂数据类型之指针
【30天熟悉Go语言】6 Go 复杂数据类型之指针
从方法执行的堆栈信息来看,在method a中variable的内存地址为510,在method b中variable的内存地址为505。

三、总结

指针呢就是内存地址,类比理解为java中的引用类型。额外再记忆两个运算符、一个公式。

两个运算符:

  • & :取变量的存储地址
  • *:指针取值,取指针变量对应的数值

一个公式:文章来源地址https://www.toymoban.com/news/detail-493324.html

  • ptr := &v
    • v 是被取内存地址的变量;
    • 变量ptr用于接收变量v的内存地址。
    • 基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型,比如:int的对应的指针为*int

到了这里,关于【30天熟悉Go语言】6 Go 复杂数据类型之指针的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【30天熟悉Go语言】3 怀着Java看Go的编程规约

    Go系列文章: GO开篇:手握Java走进Golang的世界 2 Go开发环境搭建、Hello World程序运行 Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html 1 源文件以 .go 结尾 2 程序的执行入口是main()函数 3 严格区分大小写 4 方法由一条条语句构成,每个语句后不需要加分号(GO会在每行后

    2024年02月06日
    浏览(42)
  • 【30天熟悉Go语言】2 Go开发环境搭建、Hello World程序运行

    Go系列文章: GO开篇:手握Java走进Golang的世界 Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html 1 进入到Go官网(https://golang.org),点击Download按钮; 2 选择操作系统对应的环境版本(图形化安装),进行下载,比如博主的windows: 3 下载完一路安装,博主的安装目录如下

    2024年02月06日
    浏览(52)
  • 【30天熟悉Go语言】7 Go流程控制之分支结构if、switch

    Go系列文章: GO开篇:手握Java走进Golang的世界 2 Go开发环境搭建、Hello World程序运行 3 Go编程规约和API包 4 Go的变量、常量、运算符 5 Go 基本数据类型 6 Go 复杂数据类型之指针 Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html if 语句由布尔表达式后紧跟一个或多个语句组

    2024年02月09日
    浏览(37)
  • 【30天熟悉Go语言】8 Go流程控制之循环结构for range、goto、break、continue

    Go系列文章: GO开篇:手握Java走进Golang的世界 2 Go开发环境搭建、Hello World程序运行 3 Go编程规约和API包 4 Go的变量、常量、运算符 5 Go 基本数据类型 6 Go 复杂数据类型之指针 7 Go流程控制之分支结构if、switch Go专栏传送链接:https://blog.csdn.net/saintmm/category_12326997.html for 循环是一

    2024年02月10日
    浏览(45)
  • Go语言之流指针类型,new函数

    计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。 我们将内存中字节的

    2024年02月16日
    浏览(36)
  • 【c语言指针详解】复杂数据结构的指针用法

    目录 一、动态内存分配 1.1 使用malloc和free函数进行内存的动态分配和释放 1.2 内存泄漏和野指针的概念和解决方法 二、复杂数据结构的指针用法 2.1 结构体指针和成员访问操作符 2.2 指针数组和指向指针的指针 2.2.1 指针数组 2.2.2 指向指针的指针 2.3 动态内存分配与结构体

    2024年02月04日
    浏览(47)
  • 【Go】Go 语言教程--数据类型(四)

    Go 语言教程–介绍(一) Go 语言教程–语言结构(二) Go 语言教程–语言结构(三) 在 Go 编程语言中,数据类型用于声明函数和变量。 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。

    2024年02月12日
    浏览(46)
  • C语言自定义数据类型(三)结构体指针

    所谓结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就指向该结构体变量。 目录 一、指向结构体变量的指针 1.1举例说明 二、指向结构体数组的指

    2024年02月06日
    浏览(46)
  • [go语言]数据类型

    目录 知识结构 整型、浮点型 1.整型 2.浮点型 复数、布尔类型 1.复数 2.布尔类型 字符与字符串 1.字符串的格式化 2.字符串的截取 3.格式化好的字符串赋值给量 4.字符串的转换 5.strings包 在Go语言中,整型数据是一种基本的数据类型,用于表示整数。Go语言提供了多种整型数据类

    2024年01月19日
    浏览(49)
  • Go语言的数据类型

    以下是go中可用的基本数据类型 1.1 布尔型bool 布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true 1.2 数值型 1、整数型 int8 有符号 8 位整型 (-128 到 127) 长度:8bit int16 有符号 16 位整型 (-32768 到 32767) int32 有符号 32 位整型 (-2147483648 到 2147483647) int64 有符号

    2024年02月06日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包