本文介绍: 比如我们定义了一个变量a := 10,这个时候可以直接通过a这个变量来读取内存中保存的10这个值。指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址。Go语言中的指针操作非常简单,我们只需要记住两个符合:&(取地址)和*(根据地址取值)变量的本质是给存储数据的内存地址起了一个好记的别名。在计算机底层a这个变量其实对应了一个内存地址。指针地址、指针类型、指针取值。
一、关于指针
要搞明白Go语言中的指针需要先指定3个概念:指针地址、指针类型、指针取值
package main
import "fmt"
func main() {
var a =10
fmt.Printf("%dn",&a) //&a指针地址(824633761976)
fmt.Printf("%dn",*&a) //*&a指针取值(10)
fmt.Printf("%Tn",&a) //%T指针类型(*int)
}
二、&取变量地址
1、&符合取地址操作
- 每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置
- Go语言中使用&字符放在变量前面对变量进行取地址操作
- Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型
- 取变量指针的语法如下:
ptr := &v //比如v的类型为T
package main
import "fmt"
func main() {
var a = 10
var b= &a
fmt.Printf("a:%d ptr:%pn",a,&a) //a:10 ptr:0xc0000100a8
fmt.Printf("b:%v type:%Tn",b,b) // b:0xc0000100a8 type:*int
fmt.PrintIn("取b的地址:",&b) // 取 b 的地址: 0xc000006028
}
2、b := &a的图示
三、指针修改数据
1、*指针取值
package main
import "fmt"
func main() {
a := 10
b := &a //取变量a的地址,将地址保存到指针b中
fmt.Printf("type of b:%Tn",b) //type of b:*int
c := *b //指针取值(根据指针的值去内存取值)
fmt.Printf("type of c:%Tn",c) //type of c:int
fmt.Printf("value of c:%vn",c) //value of c:10
}
2、指针传值示列
package main
import "fmt"
func modify1(x int) {
x = 100
}
func modify1(x *int) {
x = 100
}
func main() {
a := 10
modify1(a)
fmt.Println(a) // 10
modify2(&a)
fmt.Println(a) // 100
}
四、new和make
1、执行报错
- 执行下面的代码会引发panic,为什么呢?
- 在Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储
- 而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间
- 要分配内存,就引出来今天的new和make
- Go语言中new和make是内建的两个函数,主要用来分配内存
package main
import "fmt"
func main() {
var userinfo map[string]string
userinfo["username"] = "Snail"
fmt.Println(userinfo)
}
/*
panic: assignment to entry in nil map
*/
2、make和new比较
package main
import "fmt"
func main() {
a := make([]int,3,10) //切片长度为1,预留空间长度为10
a = append(a,1)
fmt.Printf("%v--%Tn",a,a) //[0 0 0]--[]int 值--切片本身
var b = new([]int)
//b = b.append(b,2) // 返回的是内存指针,所以不能直接 append
*b = append(*b, 3) // 必须通过 * 指针取值,才能进行 append 添加
fmt.Printf("%v--%T",b,b) // &[]--*[]string 内存的指针---内存指针
}
3、new函数
package main
import "fmt"
func main() {
//1.new实例化int
age := new(int)
*age =1
//2、new实例化切片
li := new([]int)
*li = append(*li,1)
//3、实例化map
userinfo := new(map[string]string)
*userinfo = map[string]string{}
{*userinfo}["username"] = "Snail"
fmt.PrintIn(userinfo) //&map[username:Snail]
}
package main
import "fmt"
func main() {
var s *student
s = new(student) //分配空间
s.name = "Snail"
fmt.PrintIn(s) //&{Snail 0}
}
type Student struct {
name string
age int
}
4、make函数
- make也是用于内存分配的,但是和new不同,它只用于chan、map以及slice的内存创建
- 而且它返回的类型就是这三个类型本身,而不是他们的指针类型
- 因为这三种类型就是引用类型,所以就没有必要返回他们的指针了
package main
import "fmt"
func main() {
a := make([]int,3,10) //切片长度为1,预留空间长度为10
b := make(map[string]string)
c := make(chan int,1)
fmt.PrintIn(a,b,c) //[0 0 0] map[] 0xc0000180e0
}
原文地址:https://blog.csdn.net/MrWangisgoodboy/article/details/134723572
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_40954.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。