go语言有没有指针 go语言指针和c++一样吗

GO 一文搞懂指针和地址值的区别【go语言有没有指针 go语言指针和c++一样吗】 go语言中的指针和地址值,在使用上常常具有迷惑性,主要是其特殊的*、符号的使用,可能会让你摸不透,本文希望能讲清楚go语言的指针(pointer)和值(value) 。
这里先简单的对指针和地址值概念做一个定义:
这是因为go方法传递参数的方式导致的,go方法函数传递参数传递的是一个拷贝,看看下面的程序会输出什么?
答案是8 , 而不是9,因为AddAge函数修改的是学生的一个备份,而不是原始的学生对象
如果你想正确的给学生年龄增加的话,函数传递的需要是这个值的指针,如下所示:
需要注意的是,这里我们的指针传递的仍然是一个拷贝,比如,如果你将s赋值给另外一个指针地址,不会影响原有的指针,这点可以自行实践下 。
那在使用go语言开发的时候,何时该用指针何时改用地址值呢?比如考虑以下场景:
简单原则: 当你不确定该使用哪种的时候,优先使用指针
如果考虑在数组、切片、map等复合对象中使用指针和值,比如:
很多开发者会认为b会更高效,但是被传递的都是一个切片的拷贝,切片本身就是一个引用,所以这里被传递的其实没有什么区别 。
对于指针和地址值的使用,大家需要牢记的一点就是go数据传递的不可变性 , 活学活用此特点 , 在无状态函数中此特性非常有用 。
golang引用变量是不是包含指针是go语言有没有指针的 。
根据百度查询显示go语言有没有指针,golang引用类型包括切片go语言有没有指针 , 映射,通道 , 接口和函数类型 。其中引用类型表示创建go语言有没有指针的变量包含一个指向底层数据结构go语言有没有指针的指针 , 所以golang引用变量是包含指针的 。
Go又称Golang是Google开发的一种静态强类型、编译型、并发型 , 并具有垃圾回收功能的编程语言 。
Go语言使用 map 时尽量不要在 big map 中保存指针 不知道你有没有听过这么一句:在使用 map 时尽量不要在 big map 中保存指针 。好吧 , 你现在已经听过了:)为什么呢?原因在于 Go 语言的垃圾回收器会扫描标记 map 中的所有元素,GC 开销相当大,直接GG 。
这两天在《Mastering Go》中看到 GC 这一章节里面对比 map 和 slice 在垃圾回收中的效率对比 , 书中只给出结论没有说明理由,这我是不能忍的 , 于是有了这篇学习笔记 。扯那么多,Show Your Code
这是一个简单的测试程序,保存字符串的 map 和 保存整形的 map GC 的效率相差几十倍,是不是有同学会说明明保存的是 string 哪有指针?这个要说到 Go 语言中 string 的底层实现了 , 源码在 src/runtime/string.go里,可以看到 string 其实包含一个指向数据的指针和一个长度字段 。注意这里的是否包含指针,包括底层的实现 。
Go 语言的 GC 会递归遍历并标记所有可触达的对象,标记完成之后将所有没有引用的对象进行清理 。扫描到指针就会往下接着寻找,一直到结束 。
Go 语言中 map 是基于 数组和链表 的数据结构实现的 , 通过 优化的拉链法 解决哈希冲突,每个 bucket 可以保存8对键值,在8个键值对数据后面有一个 overflow 指针,因为桶中最多只能装8个键值对,如果有多余的键值对落到了当前桶,那么就需要再构建一个桶(称为溢出桶),通过 overflow 指针链接起来 。
因为 overflow 指针的缘故,所以无论 map 保存的是什么,GC 的时候就会把所有的 bmap 扫描一遍 , 带来巨大的 GC 开销 。官方 issues 就有关于这个问题的讨论, runtime: Large maps cause significant GC pauses #9477

推荐阅读