The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
leeraya

go 语言就很离谱

  •  
  •   leeraya · Oct 29, 2020 · 12148 views
    This topic created in 2197 days ago, the information mentioned may be changed or developed.

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

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

    64 replies  •  2020-11-30 12:45:23 +08:00
    THESDZ
    THESDZ
    Oct 29, 2020
    1
    是不是指针的问题,导致被最后一个覆盖了
    Glauben
    Glauben
    Oct 29, 2020
    2
    你是怎么生成的,上代码
    QingXuJiaZhi
    QingXuJiaZhi
    Oct 29, 2020❤️4
    3
    为什么要这样问问题…… 标题引战,正文又不上代码。
    geebos
    geebos
    Oct 29, 2020
    4
    你要保存函数指针啊
    hakono
    hakono
    Oct 29, 2020
    5
    感觉 lz 这样搞,很可能是自己的问题。。。。
    guader
    guader
    Oct 29, 2020❤️12
    6
    鱼 好大的鱼 虎纹鲨鱼
    keepeye
    keepeye
    Oct 29, 2020
    7
    若不是你自己的问题,我吃屎
    FinnBai
    FinnBai
    Oct 29, 2020
    8
    应该是 go 的经典问题,循环的时候传指针了
    leeraya
    leeraya
    OP
    Oct 29, 2020
    9
    例如:
    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
    FlyingDough
    Oct 29, 2020
    10
    怪 Go?
    rrfeng
    rrfeng
    Oct 29, 2020
    11
    不怪 Go
    coderxy
    coderxy
    Oct 29, 2020
    12
    你这是循环的时候错误的使用了指针吧
    lcdtyph
    lcdtyph
    Oct 29, 2020 via iPhone
    13
    for index, name1 := range xxx {
    index, name1 := index, name1
    // the rest code...
    }
    hakono
    hakono
    Oct 29, 2020❤️1
    14
    看了 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
    hakono
    Oct 29, 2020❤️5
    15
    都忘了 V2EX 不能回复 Markdown 了
    例子: https://play.golang.org/p/4qyRFCv2AMF

    关于 for range 这个, 我一般是不太喜欢使用 for idx, value := slice1 的写法的, 因为 value 是指的拷贝,每次循环都要拷贝一遍,大量循环的时候性能会有影响,所以默认都是 for idx := slice1 这样
    wangyzj
    wangyzj
    Oct 29, 2020 via iPhone
    16
    函数指针
    BoarBoar
    BoarBoar
    Oct 29, 2020
    17
    这不都是很基础的东西吗,传值还是传指针,深拷贝浅拷贝我记得是大一学的
    函数作为一等公民也是 js 等脚本语言广泛使用的
    所以我一直觉得与其学多少新东西,先打好基础才是最重要的,很多东西大同小异,万变不离其宗
    leeraya
    leeraya
    OP
    Oct 29, 2020
    19
    @hakono 太牛了,感谢大佬。
    wander639
    wander639
    Oct 29, 2020
    20
    可以新开一贴:用 go 语言的人就很离谱
    lookbackagain
    lookbackagain
    Oct 29, 2020
    21
    这么基础的问题,怪 go 语言就离谱
    yufpga
    yufpga
    Oct 29, 2020❤️1
    22
    // 自己细品
    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)
    }
    Yooloo
    Yooloo
    Oct 29, 2020
    23
    ??? 这问题还能怪 Go 啊?
    gowk
    gowk
    Oct 29, 2020 via Android❤️2
    24
    滚!
    gowk
    gowk
    Oct 29, 2020❤️1
    25
    忘加狗头了
    mrgeneral
    mrgeneral
    Oct 29, 2020
    26
    一个帖子多重反转。
    看标题我就知道要引战了。
    看内容没想到连代码都没贴就开始提问题了,得学习下「如何提问」
    看了贴出来的代码,没想到是一个很基础的问题,得学习下「 The Go Programming Language 」。

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

    最后,其实是楼主标题党了。
    realbender
    realbender
    Oct 29, 2020
    27
    去面试这样子笔试都过不了的
    yaphets666
    yaphets666
    Oct 29, 2020
    28
    javascript 这有类似的问题
    JerryChan31
    JerryChan31
    Oct 29, 2020❤️2
    29
    这贴是对 Cunningham's Law 的伟大实践(手动狗头
    vZexc0m
    vZexc0m
    Oct 29, 2020
    30
    @hakono #14 但是为什么 test 内部三个函数的地址却还是一样的呢
    ghjacky
    ghjacky
    Oct 29, 2020
    31
    你这不是 go 的问题吧,这是对编程里边的 for 循环有异议?
    GopherDaily
    GopherDaily
    Oct 29, 2020
    32
    怪我,不用说了
    chengyunbo
    chengyunbo
    Oct 29, 2020
    33
    新手上路基本都会碰到这个坑,特别是从 PHP 转过来的,趟坑多了,慢慢体会,我已经趟了一路了。
    zu1k
    zu1k
    Oct 29, 2020 via Android
    34
    看了一遍,又浪费时间了
    hakono
    hakono
    Oct 29, 2020
    35
    @vZexc0m 涉及到底层所以不是非常了解,但从理解上来说,闭包调用的时候函数定义和环境是分开的,所以环境虽然不同,但是指向的都是同一个地址
    yuhaoyuhao
    yuhaoyuhao
    Oct 29, 2020
    36
    @vZexc0m 我觉得应该算是一种编译器优化。
    index90
    index90
    Oct 29, 2020
    37
    @vZexc0m 函数地址肯定都是一样的呀,了解一下 linux 进程内存模型,函数都在代码段里。

    编码时候看起来是函数是个变量,实际上只有一个函数的代码段,函数内的变量实际上是参数。
    wellsc
    wellsc
    Oct 29, 2020
    38
    这个坑就离谱
    victor
    victor
    Oct 29, 2020
    39
    基础差不要紧,请用 https://github.com/kyoh86/scopelint 检查 range 的写法。
    kkbblzq
    kkbblzq
    Oct 29, 2020
    40
    这个贴就很离谱
    misaka19000
    misaka19000
    Oct 29, 2020
    41
    V 站的提问质量每况愈下
    Zhangxiaopa
    Zhangxiaopa
    Oct 29, 2020
    42
    @mrgeneral 但是楼主成功了
    sulinehk
    sulinehk
    Oct 29, 2020❤️1
    43
    这个坑还常见的,以前写过一篇博客: https://www.sulinehk.com/post/golang-closure-details/
    bigNewsMaker
    bigNewsMaker
    Oct 29, 2020 via iPhone
    44
    不要老是想着搞一个大新闻~
    yulon
    yulon
    Oct 29, 2020❤️2
    45
    天天 Go 语言离谱,JS 离谱的,来写 C++ 嘛,求求你们来写 C++ 嘛,赚得还更多,为啥不来写捏
    xuanbg
    xuanbg
    Oct 29, 2020
    46
    这不是和在一个循环里面把一个对象属性改改放进去 list,然后发现整个 list 里面的对象属性全都和最后一个一样一回事嘛。
    xuanbg
    xuanbg
    Oct 29, 2020
    47
    @yulon C 艹在他们手里就更离谱了🐶
    shm7
    shm7
    Oct 29, 2020 via iPhone
    48
    函数返回有类型很奇怪吗?
    ————-
    PHP 就很离谱
    Python 就很离谱
    JS 就很离谱
    Lua 就很离谱
    Lisp 就很离谱
    C 就很离谱
    C++就很离谱
    Java 就很离谱
    GO 就很离谱

    ————-
    计算机就是离谱
    人类就是离谱
    地球就是离谱
    银河系就是离谱
    宇宙就是离谱
    大爆炸就是离谱
    coderunI
    coderunI
    Oct 29, 2020
    49
    这不就是 js 经典闭包问题吗?
    QingXuJiaZhi
    QingXuJiaZhi
    Oct 29, 2020
    50
    @sulinehk 博客样式很好看
    MemoryCorner
    MemoryCorner
    Oct 29, 2020
    51
    楼主就很离谱
    eudore
    eudore
    Oct 30, 2020
    52
    楼主就很离谱
    mscb
    mscb
    Oct 30, 2020 via Android
    53
    一定要先学好基础
    WaldenHorizon
    WaldenHorizon
    Oct 30, 2020
    54
    很遗憾看不到 7 楼吃屎
    Hider5
    Hider5
    Oct 30, 2020
    55
    楼主就很离谱
    deplives
    deplives
    Oct 30, 2020
    56
    楼主就很离谱
    OMGZui
    OMGZui
    Oct 30, 2020
    57
    楼主就很离谱
    shineqaq
    shineqaq
    Oct 30, 2020
    58
    楼主就很离谱
    jewer3330
    jewer3330
    Oct 30, 2020
    59
    楼主就很离谱
    JB18CM
    JB18CM
    Oct 30, 2020
    60
    楼主就很离谱
    WaldenHorizon
    WaldenHorizon
    Oct 30, 2020
    61
    楼主就很离谱
    xiatian0415
    xiatian0415
    Oct 30, 2020
    62
    你们不对劲
    DonkeyBenjamin
    DonkeyBenjamin
    Oct 31, 2020
    63
    任何函数是 first-class, closure 是 deep binding 的都有这种现象,不是 go 特有的
    这楼主不懂乱喷
    sunshinev
    sunshinev
    Nov 30, 2020
    64
    指针 指针 !!!!引用!!!引用
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4919 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 110ms · UTC 07:56 · PVG 15:56 · LAX 23:56 · JFK 02:56
    ♥ Do have faith in what you're doing.