16、指针-GOLANG

概念

指针是指向另一个变量的地址的变量,是一种间接访问的形势

&和*

go语言的指针采用了C语言的指针语法,在这类语法中我们需要关注&(与符号)和*(星号)

image-20230311131208733

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
answer := 100
fmt.Println(&answer)

address := &answer
fmt.Println(*address)//星号对地址变量进行取值,address变量没有存储数值100,但是它存储了内存地址,这个内存地址里面存放了100

}

image-20230311131552655

image-20230311131815600

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

func main() {
canada := "Canada"

var home *string //声明home变量为string类型的指针

home = &canada//将canada变量的内存地址赋给home
fmt.Println(*home)//利用*引用内存地址的值
}

星号放在类型前面表示声明指针的类型,星号放在指针变量前面表示解引用变量指向的值

指针的作用

指向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import "fmt"

func main() {
var administrator *string
//Charles Bolden与2009年成为NASA的局长,该职位的前任为Christopher Scolese通关指针代表局长一职
scolese := "Christopher Scolese"
administrator = &scolese
fmt.Println(*administrator)

bolden := "Charles Bolden"
administrator = &bolden
fmt.Println(*administrator)
}

指向结构的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import "fmt"

type person struct {
name string
age int
}

func main() {

timmy := &person{
name: "xiu",
age: 18,
}
fmt.Printf("%T\n %v", timmy, *timmy)
}

image-20230311160913129

自动解引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

type person struct {
name, superpower string
age int
}

func main() {

timmy := &person{
name: "xiu",
age: 18,
}

fmt.Printf("%T %v\n", timmy, timmy)
timmy.superpower = "flying" //这里就比写(*timmy).superpower更优雅
fmt.Printf("%+v\n", timmy)
}

指向数组的指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func main() {
superpower := &[3]string{//创建指向数组的指针
"flight",
"invisibility",
"super strength",
}
fmt.Printf("%T\n", superpower)
fmt.Printf("%T %v\n", superpower[0], superpower[0])
fmt.Printf("%T %v\n", superpower[1:2], superpower[1:2])
//对数组的解引用也不是必须的,go语言也提供了自动解引用的特征

}

修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

type person struct {
name, superpower string
age int
}

func birthday(p *person) {
p.age++
}
func main() {

timmy := person{
name: "xiu",
superpower: "flying",
age: 18,
}
birthday(&timmy)
fmt.Println(timmy)
}

指针接收者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

type person struct {
name, superpower string
age int
}

func (p *person) birthday() {
p.age++
}
func main() {

timmy := person{
name: "xiu",
superpower: "flying",
age: 18,
}
timmy.birthday()
fmt.Println(timmy)
}

内部指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

type statu struct {
level int
endurance, heath int
}
type character struct {
name string
stats statu
}

func levelUp(s *statu) {
s.level++
s.endurance = 42 + (14 * s.level)
s.heath = 5 * s.endurance
}
func main() {
player := character{name: "Matthias"}
levelUp(&player.stats)
fmt.Println(player.stats)
}

映射是一种隐式指针

指针和接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
"fmt"
"strings"
)

type talker interface {
talk() string
}
type martian struct{}

func (m martian) talk() string {
return "xiu xiu"
}
func shout(t talker) {
louder := strings.ToUpper(t.talk())
fmt.Println(louder)
}

func main() {
shout(martian{})
shout(&martian{})//无论是martian还是指向martian的指针都可以满足talker接口
}