V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
momowei
V2EX  ›  问与答

一个 go 问题请教

  •  
  •   momowei · 2020-10-21 09:04:53 +08:00 · 1980 次点击
    这是一个创建于 1527 天前的主题,其中的信息可能已经有所发展或是发生改变。
    func (srv *sysCommonSrv) ListCommongImg() []model.CommonImg {
    	var imgList []model.CommonImg
    	err := Db.Find(&imgList).Error
    	if nil != err {
    		return make([]model.CommonImg, 0)
    	}
    	i := 0
    	for ; i < len(imgList); i++ {
    		img1 := imgList[i]
    		fmt.Printf("%p\n", &img1)
    
    		if img1.Type2 == 1 {
    			imgList[i].Imgpath = CacheFactory.Create().GetSysConfgiByCode("sysconfig_local_imgserver") + "/" + img1.Imgpath
    		}
    		fmt.Printf("%p\n", &imgList[i])
    	}
    	return imgList
    }
    

    输出

    0xc0003f18b0
    0xc0003f1860
    

    我这里用的不是 range 遍历, img1 := imgList[i] 这也是值拷贝吗? 为啥输出的指针地址不一样呀

    10 条回复    2020-10-21 12:23:53 +08:00
    ArJun
        1
    ArJun  
       2020-10-21 09:14:52 +08:00
    img1 := 是重新创建值,imgList[i]这个是修改, 你用 imgList[i] = 就可以了
    JeromeCui
        2
    JeromeCui  
       2020-10-21 09:17:00 +08:00
    是的,值拷贝。
    var imgList []model.CommonImg 这个地方可以改成 var imgList []*model.CommonImg,之后每个元素就是一个指针了
    lcc142625
        3
    lcc142625  
       2020-10-21 09:18:27 +08:00
    对的,楼上的意思,你得改成 var imgList []*model.CommonImg,不然你的后面 img1 := 是重新赋值,地址当然不一样了
    tutuk5
        4
    tutuk5  
       2020-10-21 09:25:16 +08:00
    这个是值类型,值类型都是创建一个新的内存,只有引用类型才是创建一个指针。
    qysz
        5
    qysz  
       2020-10-21 09:25:57 +08:00
    img1 定义在 for 循环外面试试,循环内不要用 := 。
    momowei
        6
    momowei  
    OP
       2020-10-21 09:28:18 +08:00
    @JeromeCui 我以为只有 range 才是值拷贝列,这个语义跟 java 还是蛮大区别
    0xWalker
        7
    0xWalker  
       2020-10-21 09:32:15 +08:00 via iPhone
    img1 是临时变量的地址
    di1012
        8
    di1012  
       2020-10-21 11:44:37 +08:00
    img1 := imgList[i]
    等价于
    var img1 model.CommonImg
    img1=imgList[i]

    &img1 取的是新创建的变量的地址
    mcfog
        9
    mcfog  
       2020-10-21 12:11:14 +08:00 via Android
    不同于其他语言,golang 永远都是值拷贝,值传参,没有例外。指针是单纯的(值)类型,“引用”只是“解指针”动作的效果
    sunny352787
        10
    sunny352787  
       2020-10-21 12:23:53 +08:00
    记住 go 里面所有东西都是值,想改用指针
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5382 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 08:50 · PVG 16:50 · LAX 00:50 · JFK 03:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.