定义

所谓指针其实你可以把它想像成一个箭头,这个箭头指向(存储)一个变量的地址

因为这个箭头本身也需要变量来存储,所以也叫做指针变量。

Go的指针不支持那些乱七八糟的指针移位它就表示一个变量的地址。看看这个例子:

package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(x)
fmt.Println(x_ptr)
fmt.Println(*x_ptr)
}

上面例子输出x的值x的地址通过指针变量输出x的值,而x_ptr就是一个指针变量

0xc084000038

认真理清楚这两个符号的意思。

取一个变量的地址

取一个指针变量所指向的地址的值

考你一下,上面的例子中,如何输出x_ptr的地址呢?

package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(&x_ptr)
}

此例看懂,指针就懂了。

永远记住一句话,所谓指针就是一个指向(存储)特定变量地址的变量。没有其他的特别之处。

再变态一下,看看这个:

package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(*&x_ptr)
}
  1. x_ptr 是一个指针变量,它指向(存储)x的地址
  2. &x_ptr 是取这个指针变量x_ptr的地址,这里可以设想有另一个指针变量x_ptr_ptr(指向)存储这个x_ptr指针的地址
  3. &x_ptr 等价于`x_ptr_ptr就是取这个x_ptr_ptr指针变量指向(存储)地址所对应的变量的值,也就是x_ptr的值,也就是指针变量x_ptr指向(存储)的地址,也就是x的地址。 这里可以看到,其实*&`这两个运算符在一起就相互抵消作用了。

用途

指针的一大用途就是可以将变量的指针作为实参传递给函数,从而在函数内部能够直接修改实参所指向的变量值。

Go的变量传递都是值传递。

package main
import (
"fmt"
)
func change(x int) {
x =
}
func main() {
var x int =
fmt.Println(x)
change(x)
fmt.Println(x)
}

上面的例子输出结果为


很显然,change函数改变的仅仅是内部变量x,而不会改变传递进去的实参。其实,也就是说Go的函数一般关心的是输出结果,而输入参数就相当于信使跑到函数门口大叫,你们这个参数是什么值,那个是什么值,然后就跑了。你函数根本就不能修改它的值。不过如果是传递的实参是指针变量,那么函数一看,小子这次你地址我都知道了,哪里跑。那么就是下面的例子:

package main
import (
"fmt"
)
func change(x *int) {
*x =
}
func main() {
var x int =
fmt.Println(x)
change(&x)
fmt.Println(x)
}

上面的例子中,change函数的虚参为整型指针变量,所以在main中调用的时候传递的是x的地址。然后在change里面使用*x=200修改了这个x的地址的值。所以x的值就变了。这个输出是:


new

new这个函数挺神奇,因为它的用处太多了。这里还可以通过new来初始化一个指针。上面说过指针指向(存储)的是一个变量的地址,但是指针本身也需要地址存储。先看个例子:

package main
import (
"fmt"
)
func set_value(x_ptr *int) {
*x_ptr =
}
func main() {
x_ptr := new(int)
set_value(x_ptr)
//x_ptr指向的地址
fmt.Println(x_ptr)
//x_ptr本身的地址
fmt.Println(&x_ptr)
//x_ptr指向的地址值
fmt.Println(*x_ptr)
}

上面我们定义了一个x_ptr变量,然后用new申请了一个存储整型数据的内存地址,然后将这个地址赋值x_ptr指针变量,也就是说x_ptr指向(存储)的是一个可以存储整型数据的地址,然后用set_value函数将这个地址中存储的值赋值为100。所以第一个输出是x_ptr指向的地址,第二个则是x_ptr本身的地址,而*x_ptr则是x_ptr指向的地址中存储的整型数据的值

0xc084000040
0xc084000038

小结

好了,现在用个例子再来回顾一下指针。

交换两个变量的值。

package main
import (
"fmt"
)
func swap(x, y *int) {
*x, *y = *y, *x
}
func main() {
x_val :=
y_val :=
swap(&x_val, &y_val)
fmt.Println(x_val)
fmt.Println(y_val)
}

很简单吧,这里利用了Go提供的交叉赋值的功能,另外由于是使用了指针作为参数,所以在swap函数内,x_val和y_val的值就被交换了。


												

换个语言学一下 Golang (8)——指针的更多相关文章

  1. 换个语言学一下 Golang (3)——数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...

  2. 换个语言学一下 Golang (12)——Web基础

    一.web工作方式 我们平时浏览网页的时候,会打开浏览器,输入网址后按下回车键,然后就会显示出你想要浏览的内容.在这个看似简单的用户行为背后,到底隐藏了些什么呢?对于普通的上网过程,系统其实是这样做的 ...

  3. 换个语言学一下 Golang (5)——运算符

    运算符用于在程序运行时执行数学或逻辑运算. Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 接下来让我们来详细看看各个运算符的介绍. 算术运算符 下表 ...

  4. 换个语言学一下 Golang (1)

    做技术的总是有些拗.这么多年一直在.net的框框里打转转.直到现在市场上.net工作越来越难找,项目越来越老才发现不做出改变不行了.就从学习Go开始吧. Go语言的特点 简洁.快速.安全 并行.有趣. ...

  5. 换个语言学一下 Golang(14) ——fmt包

    Print() 函数将参数列表 a 中的各个参数转换为字符串并写入到标准输出中. 非字符串参数之间会添加空格,返回写入的字节数. func Print(a ...interface{}) (n int ...

  6. 换个语言学一下 Golang (13)——Web表单处理

    介绍 表单是我们平常编写Web应用常用的工具,通过表单我们可以方便的让客户端和服务器进 行数据的交互.对于以前开发过Web的用户来说表单都非常熟悉.表单是一个包含表单元素的区域.表单元素是允许用户在表 ...

  7. 换个语言学一下 Golang (11)——使用包和测试

    Go天生就是为了支持良好的项目管理体验而设计的. 包 在软件工程的实践中,我们会遇到很多功能重复的代码,比如去除字符串首尾的空格.高质量软件产品的特点就是它的部分代码是可以重用的,比如你不必每次写个函 ...

  8. 换个语言学一下 Golang (9)——结构体和接口

    基本上到这里的时候,就是上了一个台阶了.Go的精华特点即将展开. 结构体定义 上面我们说过Go的指针和C的不同,结构体也是一样的.Go是一门删繁就简的语言,一切令人困惑的特性都必须去掉. 简单来讲,G ...

  9. 换个语言学一下 Golang (4)——变量与常量

    一.变量定义 所谓的变量就是一个拥有指定名称和类型的数据存储位置. //看一个例子 package main import ( "fmt" ) func main() { var ...

随机推荐

  1. 一个半吊子PM的反思

    故事之源 2019年3月,也就是2016级计算机学院的大三时,软件工程这门课程由选修转为专业必修课,而七个葫芦娃共聚罗杰老师的课堂,组成葫芦娃不想写代码小分队.面临着继承往届项目.完成指定项目和自选项 ...

  2. docker swarm 集群搭建

    创建一个集群 [vagrant@node1 ~]$ docker swarm init --advertise-addr 192.168.9.101 Swarm initialized: curren ...

  3. 运维笔记--线上服务器git环境配置

    场景描述: 我们采用git去管理代码分支,本地开发环境,线上服务器多数情况下也会使用git去管理程序代码,那么新的一台服务器,如果指定了目标路径作为代码存放路径,该如何配置git环境, 以达到跟远程服 ...

  4. vue---引入外部样式

    在用 vue-cli 进行项目开发的时候,经常会遇到要引入外部的样式,那该怎么做的呢? 示例:使用 import 引入 scss import variables from '@/assets/sty ...

  5. Navicat连接MySQL8.0出现1251-Client does not support authentication protocol requested by server;

    因为安装的MySQL是8.0版本的,因为在安装的时候采用了新的加密方式. 我们需要使用 cmd命令,连接mysql 1.   更改加密方式 mysql> ALTER USER 'root'@'l ...

  6. Git采坑与问题排查

    目录 Case1:代码库中存大文件 Case1:代码库中存大文件 背景 有这种情况,项目运行需要依赖一个文件(比如需要读一个文件中的数据),那么最直接的方式就是将该文件添加到代码中的分支中,然后将分支 ...

  7. Dubbo的设计结构和工作原理

    (1)设计结构 Provider:暴露服务方称之为“服务提供者”. Consumer:调用远程服务方称之为“服务消费者”. Registry:服务注册与发现中心的目录服务称之为“服务注册中心”. Mo ...

  8. C# Task 暂停与取消 或 C#中可取消的Task

    (1)https://www.cnblogs.com/zhengzc/p/10724839.html (2)https://blog.csdn.net/hxfhq1314/article/detail ...

  9. [LeetCode] 768. Max Chunks To Make Sorted II 可排序的最大块数 II

    This question is the same as "Max Chunks to Make Sorted" except the integers of the given ...

  10. log4j Logger 使用简介

    项目结构: log4j.properties 内容: log4j.rootCategory=info,stdout log4j.appender.stdout=org.apache.log4j.Con ...