请教一个 go 的函数问题

2020-10-22 15:48:19 +08:00
 loriann
代码片段如下
type St struct {
Val int
}
type f Func(s *St)
func Set(i int) f {
return func(s *St){
s.Val = i
}
}

func main(){
f := Set(100)
var ss St
f(&ss)

// ss.Val = 100 ????
}

最后我好奇的是,这个 100 是怎么设置进去的,同样的代码逻辑我用 c++ s.Val 的结果完全是个随机数
2522 次点击
所在节点    Go 编程语言
28 条回复
cmdOptionKana
2020-10-22 15:56:25 +08:00
不懂 C++,想问一下 C++有没有闭包的概念?

另外 Go 会自动初始化空值,比如 var ss St 之后,ss.Val 会自动初始化为 0,这里 C++ 是类似的规定吗?
kuro1
2020-10-22 15:56:55 +08:00
f 是个 function 啊
loriann
2020-10-22 15:57:46 +08:00
c++ 没有闭包。ss.Val 是 0 我能理解,但是不太理解为什么 ss.Val 是 100
zwpaper
2020-10-22 15:58:31 +08:00
贴代码可以用 markdown 语法,```
或者 gist

这样的代码太难看了

另外,可以把 C++ 是随机数的代码也贴出来对比一下
di1012
2020-10-22 15:59:30 +08:00
ss 的地址指到了 s
kuro1
2020-10-22 15:59:35 +08:00
给你换种写法,就是个赋值而已

```
type St struct {
Val int
}

func f1(s *St, v int) {
s.Val = v
}

func TestA(t *testing.T) {
var ss St
f1(&ss, 100)

fmt.Println(ss.Val)
}
```
zwpaper
2020-10-22 15:59:59 +08:00
Orenoid
2020-10-22 16:00:13 +08:00
就通过传值设置进去的啊,你的疑问点是在于闭包?
Mitt
2020-10-22 16:00:16 +08:00
@loriann 因为闭包保存的是你闭包环境,你的闭包环境下 i 是 100,所以你执行它的时候设置的就是 100
loriann
2020-10-22 16:01:17 +08:00
@kuro1 嗯,你这样写我能理解。其实我想问的是 100 这个值存到哪里去了。它为什么能正确设置
kuro1
2020-10-22 16:04:15 +08:00
@loriann 闭包
kuro1
2020-10-22 16:07:04 +08:00
https://tour.golang.org/moretypes/25

经典闭包
```
package main

import "fmt"

func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}

func main() {
pos, neg := adder(), adder()
for i := 0; i < 10; i++ {
fmt.Println(
pos(i),
neg(-2*i),
)
}
}

```
loriann
2020-10-22 16:11:54 +08:00
@kuro1 非常感谢,闭包这个东西以前没碰到过,正在理解中。。。。
hdbzsgm
2020-10-22 16:14:43 +08:00
c++ capture list ???
catror
2020-10-22 16:30:41 +08:00
C++你把引用捕获改为赋值捕获就是 100 了
loriann
2020-10-22 16:34:24 +08:00
@catror 真是大神,佩服
lin07hui
2020-10-22 16:34:45 +08:00
Set(100) --> i = 100 --> f(&ss) --> s = &ss --> ss.Val = s.Val = i = 100
akatquas
2020-10-22 16:57:14 +08:00
go 中关于闭包的一些实现过程可以看这个, [go 闭包的实现]( https://tiancaiamao.gitbooks.io/go-internals/content/zh/03.6.html)

同时,把你的代码复制到,https://godbolt.org/ , 选择 go 语言,再选择 386gc tip,对照汇编结果来理解。
zunceng
2020-10-22 17:07:53 +08:00
@catror 正解
楼主 c++ lambda 引用了一个临时变量
loriann
2020-10-22 17:10:12 +08:00
@akatquas 谢谢,应该可以理解的更快一点了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/717494

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX