golang使用指针修改数据引起的血案


本文摘自网络,作者,侵删。

背影知识:

golang 中的struct和slice为值赋值, map为引用赋值;range语句for k, v := range val 这里的v只申明了一次,每次迭代只会更新值

我们在平时应该会经常用到用指针把修改复杂对象(struct、slice、map)属性的需求,今天小编就把踩过的一个小坑跟大家分享下:

先上下代码:

package main

import (
    "fmt"
)

// Node node
type Node struct {
    Val int
}

var nodes []Node

func initData() {
    for i := 0; i < 10; i++ {
        nodes = append(nodes, Node{
            Val: i,
        })
    }

    nodes[9].Val = 100
}
func main() {

    initData()

    var mapNodes map[int][]*Node = make(map[int][]*Node, 0)

    for _, v := range nodes {
        if _, ok := mapNodes[v.Val]; !ok {
            mapNodes[v.Val] = make([]*Node, 0)
        }
        mapNodes[v.Val] = append(mapNodes[v.Val], &v)
    }

    node := mapNodes[0][0]
    node.Val = 200

    fmt.Println(nodes)
}

输出

[{0} {1} {2} {3} {4} {5} {6} {7} {8} {100}]

期望输出

[{200} {1} {2} {3} {4} {5} {6} {7} {8} {100}]

可以明显看出我们更改的第一个元素的值没有生效,第一个原因是range造成的问题,我们不能直接使用&v去作为指向原始元素的地址,此时想得到原始元素的地址,必须明确找到元素,可以使用以下方案:

    for i, v := range nodes {
        if _, ok := mapNodes[v.Val]; !ok {
            mapNodes[v.Val] = make([]*Node, 0)
        }
        mapNodes[v.Val] = append(mapNodes[v.Val], &(nodes[i]))
    }

修改完成后,再看下输出即是我们想要的结果

[{200} {1} {2} {3} {4} {5} {6} {7} {8} {100}]

其实range语句里的v即为一个赋值操作,等价于v := nodes[i],此时的赋值操作v已经是一个新的地址和原始数据nodes[i]已经不是同一个地址,故后续想通过&v是找不到原始数据的


本文来自:简书

感谢作者:tonnyzhang

查看原文:golang使用指针修改数据引起的血案

相关阅读 >>

手撸Golang 基本数据结构与算法 插入排序

Golang如何获取目录下文件是否存在

Go语言开发分布式任务调度 轻松搞定高性能crontab

常见的 Go 处理字符串的技巧

聊聊cortex的kv.client

2.Golang 操作elasticsearch-7

手撸Golang 结构型设计模式 适配器模式

使用viper读取nacos配置(开源)

Go语言都用什么框架

Go-carbon 1.2.4 版本发布,新增系列时间比较方法

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...