递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 689|回复: 10
打印 上一主题 下一主题

[服务器] 延迟执行()与原生go语言的defer在循环中结果不一样?

[复制链接]

84

主题

763

帖子

6149

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6149
跳转到指定楼层
楼主
发表于 2024-10-28 10:51:19 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式
延迟执行()与原生go语言的defer在循环中结果不一样?

2.png (15.19 KB, 下载次数: 22)

2.png

1.png (17.94 KB, 下载次数: 21)

1.png
回复

使用道具 举报

84

主题

763

帖子

6149

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6149
11#
 楼主| 发表于 2024-10-29 07:33:43 | 只看该作者
Xelloss0618 发表于 2024-10-28 15:40
不一样,你的原生代码是直接推迟执行 Println 函数,defer会将参数值拷贝下来。

火山里会将子语句体封装 ...

谢谢,讲得明白。
回复

使用道具 举报

26

主题

1899

帖子

6920

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6920
10#
发表于 2024-10-28 15:40:09 | 只看该作者
zqiz 发表于 2024-10-28 11:35
那是书的源码,我想知道:原生与中文写法一样,为什么结果不一样呢

不一样,你的原生代码是直接推迟执行 Println 函数,defer会将参数值拷贝下来。

火山里会将子语句体封装成一个无参数的匿名函数,没有参数,自然也没有拷贝参数值。
所以匿名函数里引用的是变量本身,输出的都是变量的最后值 5。

for i := 0; i < 5; i++ {
    defer func () { fmt.Println(i) } ()
}

如果给匿名函数加个参数,就可以输出 4 3 2 1 0

for i := 0; i < 5; i++ {
    defer func (n int) { fmt.Println(n) } (i)
}
回复

使用道具 举报

144

主题

1238

帖子

5742

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
5742
QQ
9#
发表于 2024-10-28 11:47:09 | 只看该作者



火山视窗封装视频教程
回复

使用道具 举报

84

主题

763

帖子

6149

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6149
8#
 楼主| 发表于 2024-10-28 11:43:50 | 只看该作者
沉默流星 发表于 2024-10-28 11:33
建议你购买一套我的服务器封装视频教程,系统学习一下。才29.9元.当然不买也是可以的,只是个建议哈 ...

可以
回复

使用道具 举报

144

主题

1238

帖子

5742

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
5742
QQ
7#
发表于 2024-10-28 11:38:56 | 只看该作者
zqiz 发表于 2024-10-28 11:35
那是书的源码,我想知道:原生与中文写法一样,为什么结果不一样呢

很简单,你打开火山封装的延迟执行方法,看下封装的源码就明白了
火山视窗封装视频教程
回复

使用道具 举报

84

主题

763

帖子

6149

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6149
6#
 楼主| 发表于 2024-10-28 11:35:54 | 只看该作者
沉默流星 发表于 2024-10-28 11:31
方式对,要放在循环体里面把 换行格式输出 ,而不是放在延迟执行方法的方法体内

那是书的源码,我想知道:原生与中文写法一样,为什么结果不一样呢
回复

使用道具 举报

144

主题

1238

帖子

5742

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
5742
QQ
5#
发表于 2024-10-28 11:33:17 | 只看该作者
zqiz 发表于 2024-10-28 11:08
是这样吗,结果依然是

建议你购买一套我的服务器封装视频教程,系统学习一下。才29.9元.当然不买也是可以的,只是个建议哈
火山视窗封装视频教程
回复

使用道具 举报

144

主题

1238

帖子

5742

积分

贵宾

Rank: 9Rank: 9Rank: 9

积分
5742
QQ
地板
发表于 2024-10-28 11:31:38 | 只看该作者
zqiz 发表于 2024-10-28 11:08
是这样吗,结果依然是

方式对,要放在循环体里面把 换行格式输出 ,而不是放在延迟执行方法的方法体内


原因也很简单
原生你这样写就明白了
  1. // 原生代码
  2.         for i := 0; i < 5; i++ {
  3.                 defer func() {

  4.                 }()

  5.                 fmt.Println(i)

  6.         }
复制代码


火山视窗封装视频教程
回复

使用道具 举报

84

主题

763

帖子

6149

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
6149
板凳
 楼主| 发表于 2024-10-28 11:08:38 | 只看该作者
飞拓联创 发表于 2024-10-28 11:01
敢不敢把代码放线中间去

是这样吗,结果依然是

3.png (25.99 KB, 下载次数: 22)

3.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2024-11-22 14:43 , Processed in 0.102329 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表