前言
在Golang中使用 for range 语句进行迭代非常的便捷,但在涉及到指针时就得小心一点了。
下面的代码中定义了一个元素类型为 *int 的通道 ch :
package main import ( "fmt" ) func main() { ch := make(chan *int, 5) //sender input := []int{1,2,3,4,5} go func(){ for _, v := range input { ch <- &v } close(ch) }() //receiver for v := range ch { fmt.Println(*v) } }
在上面代码中,发送方将 input 数组发送给 ch 通道,接收方再从 ch 通道中接收数据,程序的预期输出应该是:
现在运行一下程序,得到的输出如下:
很明显,程序并没有达到预期的结果,那么问题出在哪里呢?我们将代码稍作修改:
//receiver for v := range ch { fmt.Println(v) }
得到如下输出:
0x416020
0x416020
0x416020
0x416020
0x416020
可以看到,5次输出变量 v ( *int )都指向了同一个地址,返回去检查一下发送部分代码:
for _, v := range input { ch <- &v }
问题正是出在这里,在 for range 语句中, v 变量用于保存迭代 input 数组所得的值,但是 v 只被声明了一次,此后都是将迭代 input 出的值赋值给 v , v 变量的内存地址始终未变,这样再将 v 的地址发送给 ch 通道,发送的都是同一个地址,当然无法达到预期效果。
解决方案:
引入一个中间变量,每次迭代都重新声明一个变量 temp ,赋值后再将其地址发送给 ch :
for _, v := range input { temp := v ch <- &temp }
抑或直接引用数据的内存(推荐,无需开辟新的内存空间):
for k, _ := range input { c <- &input[k] }
再次运行,就可看到预期的效果。以上方案是用于讨论 range 语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍详解Go语言中for range的"坑",包括了详解Go语言中for range的"坑"的使用技巧和注意事项,需要的朋友参考一下 前言 Go 中的for range组合可以和方便的实现对一个数组或切片进行遍历,但是在某些情况下使用for range时很可能就会被"坑",下面用一段代码来模拟下: 代码解析: 创建一个int slice,变量名为arr1并初始化 1,2,3 作为切片的值
在 C 语言中,数组名,&数组名,&数组首元素保存的都是同一个地址 #include <stdio.h> int main(){ int arr[3] = {1, 3, 5}; printf("%p\n", arr); // 0060FEA4 printf("%p\n", &arr); // 0060FEA4 printf("%p\n", &a
问题内容: 我目前正在学习使用Go语言编程。我在理解Go指针时遇到了一些困难(并且我的C / C ++现在很遥远…)。例如,在“第52号游览”中(http://tour.golang.org/#52),我读到: 但是如果不是 我写: 甚至: 反之亦然: 我得到了完全相同的结果。有区别吗(在内存方面,等等)? 问题答案: 您的示例使用两种Go语言规则: 可以从具有值接收器的方法派生具有指针接收器的方
问题内容: 我有以下功能: 其中,的类型是具有以下定义的接口: 题: 这是真的,和是 通过按引用 ,并且有它的价值被复制? 我认为: 是通过引用的,因为它是一张地图 是一个结构。因此,我应该传递指针以避免复制数据 问题答案: 接口类型只是一组方法。请注意,接口定义的成员未指定接收方类型是否为指针。这是因为 值类型的方法集是其关联的指针类型的方法集的子集 。满嘴 我的意思是,如果您具有以下条件: 然
本文向大家介绍详解关于MySQL 8.0走过的坑,包括了详解关于MySQL 8.0走过的坑的使用技巧和注意事项,需要的朋友参考一下 今天手贱更新了MySQL 8.0 第一个问题:Navicat连接不上数据库 安装的mysql为localhost:3306,配置一切默认,安装后打开Navicat 12 新建连接,直接报错 authentication plugin 'caching_sha2_pas
本文向大家介绍golang方法中receiver为指针与不为指针的区别详析,包括了golang方法中receiver为指针与不为指针的区别详析的使用技巧和注意事项,需要的朋友参考一下 前言 golang的指针receiver和非指针receiver的区别?最近在看网站有同学提问golang中方法的receiver为指针和不为指针有什么区别,在这里我以简单易懂的方法进行说明,帮助刚刚学习golang