go for range的坑

package main

import "fmt"

func main() {
	ParseStudent()
}

type student struct {
	Name string
	Age  int
}

func ParseStudent() {
	m := make(map[string]*student)
	stus := []student{
		{Name: "zhang", Age: 22},
		{Name: "li", Age: 23},
		{Name: "wang", Age: 24},
	}
	for _, stu := range stus {
		// 都指向了同一个stu的内存指针,为什么?
		// 因为 for range 中的 v 只会声明初始化一次
		// 不会每次循环都初始化,最后赋值会覆盖前面的

		fmt.Printf("%p\\n", &stu)

		// 1. bad
		// 这里map的值是stu的地址
		m[stu.Name] = &stu

		// 2. good
		/*newStu := stu
		  m[stu.Name] = &newStu*/
	}

	for i, v := range m {
    // 这里打印将会是地址指向的值,因为地址不变,所以指向同一个值
		fmt.Println(i, *v)
	}
}

// 结果
0xc0000044a0
0xc0000044a0
0xc0000044a0
zhang {wang 24}
li {wang 24}
wang {wang 24}


// 将上面代码的good注释取消,将bad注释掉

package main

import "fmt"

func main() {
	ParseStudent()
}

type student struct {
	Name string
	Age  int
}

func ParseStudent() {
	m := make(map[string]*student)
	stus := []student{
		{Name: "zhang", Age: 22},
		{Name: "li", Age: 23},
		{Name: "wang", Age: 24},
	}
	for _, stu := range stus {
		// 都指向了同一个stu的内存指针,为什么?
		// 因为 for range 中的 v 只会声明初始化一次
		// 不会每次循环都初始化,最后赋值会覆盖前面的

		fmt.Printf("%p\\n", &stu)

		//// 1. bad
		//
		//m[stu.Name] = &stu

		// 2. good
		newStu := stu
		m[stu.Name] = &newStu
	}

	for i, v := range m {
		fmt.Println(i, *v)
	}
}

// 结果
0xc0000044a0
0xc0000044a0
0xc0000044a0
wang {wang 24}
zhang {zhang 22}
li {li 23}
posted @ 2020-11-10 10:57  LinuxSFeng  阅读(84)  评论(0编辑  收藏  举报