Golang中range指针数据的坑

栏目: C · 发布时间: 6年前

内容简介:在Golang中使用下面的代码中定义了一个元素类型为在上面代码中,发送方将

在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 出的值赋值给 vv 变量的内存地址始终未变,这样再将 v 的地址发送给 ch 通道,发送的都是同一个地址,当然无法达到预期效果。

解决方案是,引入一个中间变量,每次迭代都重新声明一个变量 temp ,赋值后再将其地址发送给 ch

for _, v := range input {
    temp := v
    ch <- &temp
}

抑或直接引用数据的内存(推荐,无需开辟新的内存空间):

for k, _ := range input {
    c <- &input[k]
}

再次运行,就可看到预期的效果。以上方案是用于讨论 range 语句带来的问题,当然,平时还是尽量避免使用指针类型的通道。


以上所述就是小编给大家介绍的《Golang中range指针数据的坑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

你的品牌,价值千万

你的品牌,价值千万

温迪 / 人民邮电出版社 / 2018-7-1 / 49.00元

“大道无术,万法归心。” 不管是互联网、社交媒体,还是 AI 怎样让人眼花缭乱。从“真心”出发塑造的个人品牌,都将带你从容面对任何一种变化的冲击。现代生活变得越来越透明,如果你不懂得如何真实、精准地定位和呈现自己,你的个人品牌在 碎片信息中被误解、被曲解就是一种必然。 本书分四步引导你剖析自己、发现自我,构建可持续的品牌生态系统,策划品牌战略,提升个人呈现力,并在最后带你勾画出一幅完整的个人......一起来看看 《你的品牌,价值千万》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具