居然还有 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
为什么要这样问问题…… 标题引战,正文又不上代码。
|
4
geebos 2020-10-29 11:50:24 +08:00
你要保存函数指针啊
|
5
hakono 2020-10-29 11:50:37 +08:00
感觉 lz 这样搞,很可能是自己的问题。。。。
|
6
guader 2020-10-29 11:51:18 +08:00 12
鱼 好大的鱼 虎纹鲨鱼
|
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 1
看了 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 5
都忘了 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 2
|
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 1
// 自己细品
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 2
滚!
|
25
gowk 2020-10-29 14:10:47 +08:00 1
|
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 2
这贴是对 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 1
这个坑还常见的,以前写过一篇博客: 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 2
天天 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
指针 指针 !!!!引用!!!引用
|