Golang -- range小坑铭记

2023-05-26,,

废话少叙,先上一段代码,猜猜预期的效果。

package main

import (
"fmt"
) type student struct {
Name string
Age int
} func main() {
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.Printf("%+v\n", m) for k, v := range m {
fmt.Printf("k:%s v:%v\n", k, v)
}
}

  out:

    map[zhou:0x42114e100 li:0x42114e100 wang:0x42114e100]
  k:li v:&{wang 22}
   k:wang v:&{wang 22}
  k:zhou v:&{wang 22}

  是不是很诧异,结果为什么不是预期的,map的值都是一个呢?

  原因:for range每次产生的 k , v 都是一个值拷贝,不是 stus对应值得引用,故而会出现这种结果。

  细节分析:

  for _, stu := range stus {
m[stu.Name] = &stu
  }   // stu 是在 for中申请的一个局部变量,地址为:0x42114e100, 每次拷贝stus中对应的值。
  // 迭代遍历之后,stu每次被重新赋值,而map记录的是 变量stu对应的地址值,故而不会产生预期的效果。

  快速解决办法:

    for _, stu := range stus {
  a := stu
  m[stu.Name] = &a
    }

  谨在此记录。

Golang -- range小坑铭记的相关教程结束。

《Golang -- range小坑铭记.doc》

下载本文的Word格式文档,以方便收藏与打印。