指针
Go 值与指针
与
- 类型指针,允许对这个指针类型的数据进行修改,传递数据可以直接使用指针,而无须拷贝数据,类型指针不能进行偏移和运算。
- 切片,由指向起始元素的原始指针、元素数量和容量组成。
受益于这样的约束和拆分,
指针地址和指针类型
一个指针变量可以指向任何一个值的内存地址,它所指向的值的内存地址在
ptr := &v // v 的类型为 T
其中*T
,称做*
代表指针。指针实际用法,可以通过下面的例子了解:
package main
import (
"fmt"
)
func main() {
var cat int = 1
var str string = "banana"
fmt.Printf("%p %p", &cat, &str)
}
// 0xc042052088 0xc0420461b0
代码说明如下:
- 第
8 行,声明整型变量cat 。 - 第
9 行,声明字符串变量str 。 - 第
10 行,使用fmt.Printf 的动词%p
打印cat 和str 变量的内存地址,指针的值是带有0x
十六进制前缀的一组数据。
提示:变量、指针和地址三者的关系是,每个变量都拥有地址,指针的值就是地址。
从指针获取指针指向的值
当使用*
操作符,也就是指针取值,代码如下。
package main
import (
"fmt"
)
func main() {
// 准备一个字符串类型
var house = "Malibu Point 10880, 90265"
// 对字符串取地址, ptr类型为*string
ptr := &house
// 打印ptr的类型
fmt.Printf("ptr type: %T\n", ptr)
// 打印ptr的指针地址
fmt.Printf("address: %p\n", ptr)
// 对指针进行取值操作
value := *ptr
// 取值后的类型
fmt.Printf("value type: %T\n", value)
// 指针取值后就是指向变量的值
fmt.Printf("value: %s\n", value)
}
ptr type: *string
address: 0xc0420401b0
value type: string
value: Malibu Point 10880, 90265
取地址操作符&
和取值操作符*
是一对互补操作符,&
取出地址,*
根据地址取出地址指向的值。变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:
- 对变量进行取地址操作使用
&
操作符,可以获得这个变量的指针变量。 - 指针变量的值是指针地址。
- 对指针变量进行取值操作使用
*
操作符,可以获得指针变量指向的原变量的值。
使用指针修改值
通过指针不仅可以取值,也可以修改值。前面已经演示了使用多重赋值的方法进行数值交换,使用指针同样可以进行数值交换,代码如下:
package main
import "fmt"
// 交换函数
func swap(a, b *int) {
// 取a指针的值, 赋给临时变量t
t := *a
// 取b指针的值, 赋给a指针指向的变量
*a = *b
// 将a指针的值赋给b指针指向的变量
*b = t
}
func main() {
// 准备两个变量, 赋值1和2
x, y := 1, 2
// 交换变量值
swap(&x, &y)
// 输出变量值
fmt.Println(x, y)
}
// 2 1
*
操作符作为右值时,意义是取指针的值,作为左值时,也就是放在赋值操作符的左边时,表示*
操作符的根本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值,当操作在左值时,就是将值设置给指向的变量。如果在
package main
import "fmt"
func swap(a, b *int) {
b, a = a, b
}
func main() {
x, y := 1, 2
swap(&x, &y)
fmt.Println(x, y)
}
// 1 2
结果表明,交换是不成功的。上面代码中的
案例:使用指针变量获取命令行的输入信息
package main
// 导入系统包
import (
"flag"
"fmt"
)
// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
func main() {
// 解析命令行参数
flag.Parse()
// 输出命令行参数
fmt.Println(*mode)
}
// go run main.go --mode=fast
由于之前已经使用mode *string
指针,在

使用new 创建指针
new(类型)
str := new(string)
*str = "Go语言教程"
fmt.Println(*str)