【Go基础学习 一】 指针和地址

Go语言基础学习 指针和地址

有几个很不错的学习教程,感觉很不错

  • GitHub开源go学习教程 https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/preface.md
  • B站教程 https://space.bilibili.com/322210472/channel/detail?cid=108884
  • Go语言程序设计中文版 https://docs.hacknode.org/gopl-zh/ch2/ch2-03.html

最后就是go官网了

  • https://golang.org/doc/
  • go官网练习 https://tour.golang.org/list

指针和地址

上来咱就讲指针和地址,go各种数据类型,字符串,数组,map看看语法,多敲敲
可以参考 https://docs.hacknode.org/gopl-zh/ch2/ch2-03.html 这一章节。
可以参考下知乎问题为什么要有指针

我现在的理解就是, 指针通俗来讲就是内存地址,直接通过内存地址修改某个值,这是最直接,也是效率最高的。

下面是练习指针代码,给指针赋值地址 通过地址取值

如果用“var x int”声明语句声明一个x变量,那么&x表达式(取x变量的内存地址)将产生一个指向该整数变量的指针,指针对应的数据类型是*int,指针被称之为“指向int类型的指针”。

package main

import "fmt"

func main() {
	a := 123
	fmt.Println(a)
	var b *int // 定义b为指针类型
	b = &a     // & 取地址符号
	*b = 666   // 表示的就是值 
	fmt.Println(a, &a, b, *b, &*b)
	// 函数传入地址, 函数内部可以修改值
	changeA1(&a) // &取地址 指向该变量的指针 所以函数用 *int接收
	fmt.Println(a) // 777
	changeA2(a)
	fmt.Println(a) // 还是777 不会变成888
	// 同理其他 数据类型 数组 map struct等 可以定义指针

}

func changeA1(z *int) {
	// 使用指针可以改变原来的值 
	*z = 777
}

func changeA2(n int) {
	// 不能改变原来的值
	n = 888
}

计数的例子

import "fmt"

func counter(i *int){
	*i ++
}

func main() {

	p := 1
	counter(&p)
	counter(&p)
	counter(&p)
	fmt.Println(p)  // 输出 4
}

指针类型的赋值

package main

import "fmt"

func counter(i *int){
	*i ++
}

func main() {

	// 创建一个 int 类型的值
	n := 1

	//p := new(int) new只是一个新的语法糖  相当于 var p *int
	var p *int

	// 把n变量的地址 赋值给 int指针类型变量 p 
	p = &n

	// 传入n的地址 (n的地址指向 n变量的指针)
	counter(&n)
	
	// 输出 int指针 类型的变量 p 的值
	fmt.Println(*p) // 2

	// *p 和 n 地址指向 同一地址
	fmt.Println(&(*p) == &n)  // true

}

复杂数据类型的指针

package main

import (
	"fmt"
)


func main() {
	a := [3]string{"a", "b", "c"}
	// 定义一个数组指针 外部是一个指针 内部是元素
	var b *[3]string

	b = &a
	// 先通过*b取出array值 然后修改 array里面的值
	(*b)[0] = "zzz"

	fmt.Println(a)

	c := [3]string{"q", "w", "e"}

	// 定义一个指针数组 外部是array 里面元素是指针
	d := [3]*string{&c[0], &c[1], &c[2]}
	fmt.Println(c)
	*d[0] = "qqqqq"
	fmt.Println(d, *d[0])
	fmt.Println(c)

	// 定义一个map key为值 value为 字符串指针
	e := map[string]*string{}
	f := "r"
	e["a"] = &f
	fmt.Println("e是", e)

	// 定义一个map key value都为 字符串指针
	g := map[*string]*string{}
	h := "t"
	i := "y"
	// 字符串指针 key赋予地址 value也赋予地址
	g[&h] = &i
	fmt.Println("g是", g, "取value值", *g[&h])
}

结构体指针

package main

import "fmt"

// 定义一个结构体
type Cat struct {
	name string
	color string
	sex bool
}


func main() {
    // 实例化
	tom := Cat{
		name:"Tom",
		color:"white",
		sex: true,
	}
	fmt.Println(tom)

	// 定义一个结构体指针
	var tom2 *Cat
	// 地址赋值给结构体指针
	tom2 = &tom

	fmt.Println(tom)
	// 结构体指针改变 值
	(*tom2).name = "old tom"
	
	fmt.Println(tom)
}

传入指针和值的最直接的区别。

package main

import "fmt"

type Foo struct {
	Name string `json:"name"`
}

// 传入指针 直接传入地址修改原来的值
func (f *Foo) ModifyName(a string){
	f.Name = a
}

// 传入值 相当于copy 对原来的值不影响
func (f Foo) NotModifyName(a string){
	f.Name = a
}

func main() {
	//fmt.Printf("Hello World")

	f := Foo{Name:"Nike"}
	// 不能修改f对象的值
	f.NotModifyName("not new name")
	// 可以修改对象的值
	//f.ModifyName("new name")

	fmt.Println(f)
}

更多练习代码关注个人博客

个人博客 https://www.charmcode.cn/article/2020-07-26_Go_lets_go

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值