for...range的坑

由于本人是python开发出身,知识浅薄,没有学习过指针、内存之类的知识,如今转为golang,多少都会踩一些指针之类的坑,本章就记录一下自己踩过的相关的坑

当我们用golang写for循环时,一定要注意一个事情,那就是for后面跟的变量每次循环都是同一个指针地址!详情请看代码

package main

import (
    "fmt"
)

func main() {
    sList := []string{"1", "2", "3"}
    for _, v := range sList {
        fmt.Printf("%p \n", &v)
    }
}

输出结果(每次输出的地址都不同,但是三行都是同一个值)

0xc00000e1e0
0xc00000e1e0
0xc00000e1e0

这说明,当Go在运行for循环时,在for语句上所建立的变量(如v),每次都是使用同一个内存地址,当你进行以下的操作时就会出现严重的错误

func pase_student() {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        m[stu.Name] = &stu
    }
    fmt.Println(m)
}

输出

map[zhou:0xc00000a080 li:0xc00000a080 wang:0xc00000a080]

这个map中三个值是指向同一个内存地址的!这显然不是我们想要的,所以如果遇到以上的情况时,需要额外赋值:

func pase_student() {
    m := make(map[string]*student)
    stus := []student{
        {Name: "zhou", Age: 24},
        {Name: "li", Age: 23},
        {Name: "wang", Age: 22},
    }
    for _, stu := range stus {
        st := stu
        m[stu.Name] = &st
    }
    fmt.Println(m)
}

这样就不会出现上面的问题,因为在for循环代码块中所新建的值(如a),随着循环的进行每次都会是不同的内存地址

我们在写代码的时候一定要搞清楚什么时候该用指针,什么时候不该用,否则很容易就会出现我遇到的这种问题

本文主要记录自己在开发过程的所踩的坑,如果理解错误,欢迎评论指正~

你可能感兴趣的:(for...range的坑)