跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • go 语言就很离谱
未分類
2020 年 11 月 2 日

go 语言就很离谱

go 语言就很离谱

資深大佬 : leeraya 3

居然还有 func type 这种东西。今天遇到要循环生成 type func 的对象: type FieldResolveFn func(p ResolveParams) (interface{}, error)

结果循环生成的 func 都是一样的,最后都变成可最后生成的那一个。 该怎么解决啊,老哥们

大佬有話說 (63)

  • 資深大佬 : THESDZ

    是不是指针的问题,导致被最后一个覆盖了

  • 資深大佬 : 2435043xia

    你是怎么生成的,上代码

  • 資深大佬 : cmdOptionKana

    为什么要这样问问题…… 标题引战,正文又不上代码。

  • 資深大佬 : geebos

    你要保存函数指针啊

  • 資深大佬 : hakono

    感觉 lz 这样搞,很可能是自己的问题。。。。

  • 資深大佬 : guader

    鱼 好大的鱼 虎纹鲨鱼

  • 資深大佬 : keepeye

    若不是你自己的问题,我吃屎

  • 資深大佬 : baiyi

    应该是 go 的经典问题,循环的时候传指针了

  • 主 資深大佬 : leeraya

    例如:
    type Greeting func(name string) string
    func main() {

    test := make([]Greeting, 3)

    nameArr := []string{“lee”, “ray”, “Pool”}

    for index, name1 := range nameArr {
    // if index == 0 {
    // test[index] = func(name string) string {
    // fmt.Println(“hello ” + name + name1 + strconv.Itoa(index))
    // return “hello ” + name + name1 + strconv.Itoa(index)
    // }
    // } else {
    // test[index] = func(name string) string {
    // fmt.Println(“hello ” + name + name1 + strconv.Itoa(index))
    // return “hello ” + name + name1 + strconv.Itoa(index)
    // }
    // }
    test[index] = func(name string) string {
    fmt.Println(“hello ” + name + name1 + strconv.Itoa(index))
    return “hello ” + name + name1 + strconv.Itoa(index)
    }

    }
    }
    debug 看 test 数组,元素都是一样的

  • 資深大佬 : FlyingDough

    怪 Go?

  • 資深大佬 : rrfeng

    不怪 Go

  • 資深大佬 : coderxy

    你这是循环的时候错误的使用了指针吧

  • 資深大佬 : lcdtyph

    for index, name1 := range xxx {
    index, name1 := index, name1
    // the rest code…
    }

  • 資深大佬 : hakono

    看了 LZ 的代码原来是这么回事,问题不在闭包,而是 for index, name1 := range nameArr{} 中, 每次循环都是在重复利用 name1 为 name1 赋不同的值 ,name1 本身的值在不停变换
    闭包中引用同一个变量的话,那必定是闭包的里变量的值都一样的

    https://studygolang.com/articles/14696

    “`

    for index := range nameArr {
    tmpName := nameArr[index]
    test[index] = func(name string) string {
    fmt.Println(“hello ” + name + tmpName + strconv.Itoa(index))
    return “hello ” + name + tmpName + strconv.Itoa(index)
    }

    }
    “`
    改成这样就行了

  • 資深大佬 : hakono

    都忘了 V2EX 不能回复 Markdown 了
    例子: https://play.golang.org/p/4qyRFCv2AMF

    关于 for range 这个, 我一般是不太喜欢使用 for idx, value := slice1 的写法的, 因为 value 是指的拷贝,每次循环都要拷贝一遍,大量循环的时候性能会有影响,所以默认都是 for idx := slice1 这样

  • 資深大佬 : wangyzj

    函数指针

  • 資深大佬 : BoarBoar

    这不都是很基础的东西吗,传值还是传指针,深拷贝浅拷贝我记得是大一学的
    函数作为一等公民也是 js 等脚本语言广泛使用的
    所以我一直觉得与其学多少新东西,先打好基础才是最重要的,很多东西大同小异,万变不离其宗

  • 資深大佬 : zunceng

    这个错挺常见的 理解下就好
    https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable

  • 主 資深大佬 : leeraya

    @hakono 太牛了,感谢大佬。

  • 資深大佬 : wander639

    可以新开一贴:用 go 语言的人就很离谱

  • 資深大佬 : lookbackagain

    这么基础的问题,怪 go 语言就离谱

  • 資深大佬 : yufpga

    // 自己细品
    for index, name1 := range nameArr {
    test[index] = func(i int, name1 string) Greeting {
    return func(name string) string {
    fmt.Println(“hello ” + name + name1 + strconv.Itoa(i))
    return “hello ” + name + name1 + strconv.Itoa(i)
    }
    }(index, name1)
    }

  • 資深大佬 : KaynW

    ??? 这问题还能怪 Go 啊?

  • 資深大佬 : gowk

    滚!

  • 資深大佬 : gowk

    忘加狗头了 go 语言就很离谱

  • 資深大佬 : mrgeneral

    一个帖子多重反转。
    看标题我就知道要引战了。
    看内容没想到连代码都没贴就开始提问题了,得学习下「如何提问」
    看了贴出来的代码,没想到是一个很基础的问题,得学习下「 The Go Programming Language 」。

    但凡认真学习下也不会踩这个坑: https://book.douban.com/subject/27044219/ 书里说的很明白。

    最后,其实是主标题党了。

  • 資深大佬 : realbender

    去面试这样子笔试都过不了的

  • 資深大佬 : yaphets666

    javascript 这有类似的问题

  • 資深大佬 : JerryChan31

    这贴是对 Cunningham’s Law 的伟大实践(手动狗头

  • 資深大佬 : vZexc0m

    @hakono #14 但是为什么 test 内部三个函数的地址却还是一样的呢

  • 資深大佬 : ghjacky

    你这不是 go 的问题吧,这是对编程里边的 for 循环有异议?

  • 資深大佬 : GopherDaily

    怪我,不用说了

  • 資深大佬 : chengyunbo

    新手上路基本都会碰到这个坑,特别是从 PHP 转过来的,趟坑多了,慢慢体会,我已经趟了一路了。

  • 資深大佬 : zu1k

    看了一遍,又浪费时间了

  • 資深大佬 : hakono

    @vZexc0m 涉及到底层所以不是非常了解,但从理解上来说,闭包调用的时候函数定义和环境是分开的,所以环境虽然不同,但是指向的都是同一个地址

  • 資深大佬 : yuhaoyuhao

    @vZexc0m 我觉得应该算是一种编译器优化。

  • 資深大佬 : index90

    @vZexc0m 函数地址肯定都是一样的呀,了解一下 linux 进程内存模型,函数都在代码段里。

    编码时候看起来是函数是个变量,实际上只有一个函数的代码段,函数内的变量实际上是参数。

  • 資深大佬 : wellsc

    这个坑就离谱

  • 資深大佬 : victor

    基础差不要紧,请用 https://github.com/kyoh86/scopelint 检查 range 的写法。

  • 資深大佬 : kkbblzq

    这个贴就很离谱

  • 資深大佬 : misaka19000

    V 站的提问质量每况愈下

  • 資深大佬 : Zhangxiaopa

    @mrgeneral 但是主成功了

  • 資深大佬 : sulinehk

    这个坑还常见的,以前写过一篇博客: https://www.sulinehk.com/post/golang-closure-details/

  • 資深大佬 : bigNewsMaker

    不要老是想着搞一个大新闻~

  • 資深大佬 : yulon

    天天 Go 语言离谱,JS 离谱的,来写 C++ 嘛,求求你们来写 C++ 嘛,赚得还更多,为啥不来写捏

  • 資深大佬 : xuanbg

    这不是和在一个循环里面把一个对象属性改改放进去 list,然后发现整个 list 里面的对象属性全都和最后一个一样一回事嘛。

  • 資深大佬 : xuanbg

    @yulon C 艹在他们手里就更离谱了

  • 資深大佬 : shm7

    函数返回有类型很奇怪吗?
    ————-
    PHP 就很离谱
    Python 就很离谱
    JS 就很离谱
    Lua 就很离谱
    Lisp 就很离谱
    C 就很离谱
    C++就很离谱
    Java 就很离谱
    GO 就很离谱

    ————-
    计算机就是离谱
    人类就是离谱
    地球就是离谱
    银河系就是离谱
    宇宙就是离谱
    大爆炸就是离谱

  • 資深大佬 : coderunI

    这不就是 js 经典闭包问题吗?

  • 資深大佬 : cmdOptionKana

    @sulinehk 博客样式很好看

  • 資深大佬 : MemoryCorner

    主就很离谱

  • 資深大佬 : eudore

    主就很离谱

  • 資深大佬 : mscb

    一定要先学好基础

  • 資深大佬 : wangritian

    很遗憾看不到 7 吃屎

  • 資深大佬 : Hider5

    主就很离谱

  • 資深大佬 : deplives

    主就很离谱

  • 資深大佬 : OMGZui

    主就很离谱

  • 資深大佬 : shineqaq

    主就很离谱

  • 資深大佬 : jewer3330

    主就很离谱

  • 資深大佬 : JB18CM

    主就很离谱

  • 資深大佬 : wangritian

    主就很离谱

  • 資深大佬 : xiatian0415

    你们不对劲

  • 資深大佬 : DonkeyBenjamin

    任何函数是 first-class, closure 是 deep binding 的都有这种现象,不是 go 特有的
    这主不懂乱喷

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具