主页 > 知识库 > golang中for range的取地址操作陷阱介绍

golang中for range的取地址操作陷阱介绍

热门标签:网站排名优化 地方门户网站 服务外包 AI电销 呼叫中心市场需求 百度竞价排名 铁路电话系统 Linux服务器

Tips:for range创建了每个元素的副本,而不是直接返回每个元素的引用

例子1:

package main
import "fmt"
func main() {
 slice := []int{0, 1, 2, 3}
 myMap := make(map[int]*int)
 for index, value := range slice {
  myMap[index] = value
 }
 fmt.Println("=====new map=====")
 prtMap(myMap)
}
 
func prtMap(myMap map[int]*int) {
 for key, value := range myMap {
  fmt.Printf("map[%v]=%v\n", key, *value)
 }
}

输出:

dotzdeMacBook-Pro-2:src dotz$ ./range

=====new map=====

map[0]=3

map[1]=3

map[2]=3

map[3]=3

例子2:

package main  
import "fmt"  
type Test struct {
    name string
}
 
func (this *Test) Point() { // this  为指针
    fmt.Println(this.name)
}
  
func main() {  
    ts := []Test{{"a"}, {"b"}, {"c"}}
    for _, t := range ts {
        defer t.Point() //输出 c c c
    } 
} 

输出:

dotzdeMacBook-Pro-2:src dotz$ ./method

c

c

c

例子1 我们预期输出0,1,2,3,例子2 我们预期输出a,b, c,但两个例子的输出都不是我们预期的。

对于例子1,比较明显,执行了取地址操作,每次都取value变量的地址,所以最后map中的所有元素的值都是value变量的地址(引用),因为最后value被赋值为3,所有输出都是3.

对于例子2,隐晦一点,夹杂了defer和方法接收者的规则,但其实也和例子1一样,执行t.Point()时,得到的是t的地址(引用),for结束时,t被赋值为”c“的地址,main函数返回时,都在执行”c“的接收方法Point,所以输出都是”c".

补充:golang取地址操作采坑:for idx,item := range arr中的item是个独立对象

先看代码:

package main
import "fmt"
func main() {
    type s struct {
        A string
        B int32
    }
    arr := []s{
        {"123", 123},
        {"456", 456},
        {"789", 789},
    }
    m := make(map[string]*s)
    for idx, item := range arr {
        m[item.A] = item
        fmt.Printf("idx=%d, addr=%p, item addr=%p\n", idx, arr[idx], item)
    }
    for k, v := range m {
        fmt.Printf("key=%s, v=%+v\n", k, v)
    }
}

运行输出:

idx=0, addr=0xc00004e050, item addr=0xc0000044a0

idx=1, addr=0xc00004e068, item addr=0xc0000044a0

idx=2, addr=0xc00004e080, item addr=0xc0000044a0

key=123, v={A:789 B:789}

key=456, v={A:789 B:789}

key=789, v={A:789 B:789}

我傻傻的在循环中取item的地址,结果所有map中的值都指向最后一个!

看来item是一个独立对象,这个对象指向了数组中的对应元素。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

您可能感兴趣的文章:
  • 基于golang中container/list包的用法说明
  • Golang中List的实现方法示例详解
  • golang使用grpc+go-kit模拟oauth认证的操作
  • golang如何去除多余空白字符(含制表符)
  • 用golang如何替换某个文件中的字符串
  • golang正则之命名分组方式
  • 解决golang中container/list包中的坑

标签:黄山 仙桃 湘潭 湖南 兰州 崇左 衡水 铜川

巨人网络通讯声明:本文标题《golang中for range的取地址操作陷阱介绍》,本文关键词  ;如发现本文内容存在版权问题,烦请提供相关信息告之我们,我们将及时沟通与处理。本站内容系统采集于网络,涉及言论、版权与本站无关。
  • 相关文章
  • 收缩
    • 微信客服
    • 微信二维码
    • 电话咨询

    • 400-1100-266