
居然还有 func type 这种东西。今天遇到要循环生成 type func 的对象: type FieldResolveFn func(p ResolveParams) (interface{}, error)
结果循环生成的 func 都是一样的,最后都变成可最后生成的那一个。 该怎么解决啊,老哥们
1 THESDZ 2020-10-29 11:45:03 +08:00 是不是指针的问题,导致被最后一个覆盖了 |
2 Glauben 2020-10-29 11:47:52 +08:00 你是怎么生成的,上代码 |
3 cmdOptionKana 2020-10-29 11:48:59 +08:00 为什么要这样问问题…… 标题引战,正文又不上代码。 |
4 geebos PRO 你要保存函数指针啊 |
5 hakono 2020-10-29 11:50:37 +08:00 感觉 lz 这样搞,很可能是自己的问题。。。。 |
6 guader 2020-10-29 11:51:18 +08:00 鱼 好大的鱼 虎纹鲨鱼 |
7 keepeye 2020-10-29 11:57:43 +08:00 若不是你自己的问题,我吃屎 |
8 baiyi 2020-10-29 11:58:10 +08:00 应该是 go 的经典问题,循环的时候传指针了 |
9 leeraya OP 例如: 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 数组,元素都是一样的 |
10 FlyingDough 2020-10-29 12:04:36 +08:00 怪 Go? |
11 rrfeng 2020-10-29 12:09:22 +08:00 不怪 Go |
12 coderxy 2020-10-29 12:10:18 +08:00 你这是循环的时候错误的使用了指针吧 |
13 lcdtyph 2020-10-29 12:15:37 +08:00 via iPhone for index, name1 := range xxx { index, name1 := index, name1 // the rest code... } |
14 hakono 2020-10-29 12:19:20 +08:00 看了 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) } } ``` 改成这样就行了 |
15 hakono 2020-10-29 12:22:23 +08:00 都忘了 V2EX 不能回复 Markdown 了 例子: https://play.golang.org/p/4qyRFCv2AMF 关于 for range 这个, 我一般是不太喜欢使用 for idx, value := slice1 的写法的, 因为 value 是指的拷贝,每次循环都要拷贝一遍,大量循环的时候性能会有影响,所以默认都是 for idx := slice1 这样 |
16 wangyzj 2020-10-29 12:27:06 +08:00 via iPhone 函数指针 |
17 BoarBoar 2020-10-29 12:50:10 +08:00 这不都是很基础的东西吗,传值还是传指针,深拷贝浅拷贝我记得是大一学的 函数作为一等公民也是 js 等脚本语言广泛使用的 所以我一直觉得与其学多少新东西,先打好基础才是最重要的,很多东西大同小异,万变不离其宗 |
18 zunceng 2020-10-29 13:30:51 +08:00 |
20 wander639 2020-10-29 13:44:37 +08:00 可以新开一贴:用 go 语言的人就很离谱 |
21 lookbackagain 2020-10-29 13:58:31 +08:00 这么基础的问题,怪 go 语言就离谱 |
22 yufpga 2020-10-29 14:00:09 +08:00 // 自己细品 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) } |
23 KaynW 2020-10-29 14:06:25 +08:00 ??? 这问题还能怪 Go 啊? |
24 gowk 2020-10-29 14:06:46 +08:00 via Android 滚! |
25 gowk 2020-10-29 14:10:47 +08:00 |
26 mrgeneral 2020-10-29 14:18:41 +08:00 一个帖子多重反转。 看标题我就知道要引战了。 看内容没想到连代码都没贴就开始提问题了,得学习下「如何提问」 看了贴出来的代码,没想到是一个很基础的问题,得学习下「 The Go Programming Language 」。 但凡认真学习下也不会踩这个坑: https://book.douban.com/subject/27044219/ 书里说的很明白。 最后,其实是楼主标题党了。 |
27 realbender 2020-10-29 14:23:11 +08:00 去面试这样子笔试都过不了的 |
28 yaphets666 2020-10-29 14:26:55 +08:00 Javascript 这有类似的问题 |
29 JerryChan31 2020-10-29 14:28:05 +08:00 这贴是对 Cunningham's Law 的伟大实践(手动狗头 |
31 ghjacky 2020-10-29 15:10:38 +08:00 你这不是 go 的问题吧,这是对编程里边的 for 循环有异议? |
32 GopherDaily 2020-10-29 15:14:28 +08:00 怪我,不用说了 |
33 chengyunbo 2020-10-29 15:16:46 +08:00 新手上路基本都会碰到这个坑,特别是从 PHP 转过来的,趟坑多了,慢慢体会,我已经趟了一路了。 |
34 zu1k 2020-10-29 15:26:13 +08:00 via Android 看了一遍,又浪费时间了 |
35 hakono 2020-10-29 16:22:22 +08:00 @vZexc0m 涉及到底层所以不是非常了解,但从理解上来说,闭包调用的时候函数定义和环境是分开的,所以环境虽然不同,但是指向的都是同一个地址 |
36 yuhaoyuhao 2020-10-29 16:44:16 +08:00 @vZexc0m 我觉得应该算是一种编译器优化。 |
37 index90 2020-10-29 16:46:16 +08:00 |
38 wellsc 2020-10-29 16:50:43 +08:00 这个坑就离谱 |
39 victor 2020-10-29 16:57:09 +08:00 基础差不要紧,请用 https://github.com/kyoh86/scopelint 检查 range 的写法。 |
40 kkbblzq 2020-10-29 16:57:40 +08:00 这个贴就很离谱 |
41 misaka19000 2020-10-29 17:03:55 +08:00 V 站的提问质量每况愈下 |
42 Zhangxiaopa 2020-10-29 17:14:33 +08:00 @mrgeneral 但是楼主成功了 |
43 sulinehk 2020-10-29 18:01:10 +08:00 这个坑还常见的,以前写过一篇博客: https://www.sulinehk.com/post/golang-closure-details/ |
44 bigNewsMaker 2020-10-29 18:50:45 +08:00 via iPhone 不要老是想着搞一个大新闻~ |
45 yulon 2020-10-29 19:04:52 +08:00 天天 Go 语言离谱,JS 离谱的,来写 C++ 嘛,求求你们来写 C++ 嘛,赚得还更多,为啥不来写捏 |
46 xuanbg 2020-10-29 19:08:36 +08:00 这不是和在一个循环里面把一个对象属性改改放进去 list,然后发现整个 list 里面的对象属性全都和最后一个一样一回事嘛。 |
48 shm7 2020-10-29 19:49:26 +08:00 via iPhone 函数返回有类型很奇怪吗? - PHP 就很离谱 Python 就很离谱 JS 就很离谱 Lua 就很离谱 Lisp 就很离谱 C 就很离谱 C++就很离谱 Java 就很离谱 GO 就很离谱 - 计算机就是离谱 人类就是离谱 地球就是离谱 银河系就是离谱 宇宙就是离谱 大爆炸就是离谱 |
49 coderunI 2020-10-29 21:58:31 +08:00 这不就是 js 经典闭包问题吗? |
50 cmdOptionKana 2020-10-29 22:14:51 +08:00 @sulinehk 博客样式很好看 |
51 MemoryCorner 2020-10-29 23:30:15 +08:00 楼主就很离谱 |
52 eudore 2020-10-30 08:41:04 +08:00 楼主就很离谱 |
53 mscb 2020-10-30 08:50:35 +08:00 via Android 一定要先学好基础 |
54 wangritian 2020-10-30 09:15:41 +08:00 很遗憾看不到 7 楼吃屎 |
55 Hider5 2020-10-30 09:20:35 +08:00 楼主就很离谱 |
56 deplives 2020-10-30 09:35:00 +08:00 楼主就很离谱 |
57 OMGZui 2020-10-30 10:36:31 +08:00 楼主就很离谱 |
58 shineqaq 2020-10-30 10:55:21 +08:00 楼主就很离谱 |
59 jewer3330 2020-10-30 11:13:34 +08:00 楼主就很离谱 |
60 JB18CM 2020-10-30 11:29:36 +08:00 楼主就很离谱 |
61 wangritian 2020-10-30 17:25:08 +08:00 楼主就很离谱 |
62 xiatian0415 2020-10-30 20:08:34 +08:00 你们不对劲 |
63 DonkeyBenjamin 2020-10-31 04:37:37 +08:00 任何函数是 first-class, closure 是 deep binding 的都有这种现象,不是 go 特有的 这楼主不懂乱喷 |
64 sunshinev 2020-11-30 12:45:23 +08:00 指针 指针 !!!!引用!!!引用 |