当前位置: 首页 > news >正文

德宏网站制作漯河市郾城区网站建设

德宏网站制作,漯河市郾城区网站建设,办公室装修合同范本,找人做网站 网站定制开发【Go面试向】defer与time.sleep初探 大家好 我是寸铁#x1f44a; 总结了一篇defer传参与time.sleep初探的文章✨ 喜欢的小伙伴可以点点关注 #x1f49d; 请大家看下面这段代码#xff0c;看运行结果会出现什么#xff0c;为什么#xff1f; 问题 demo package mainim…【Go面试向】defer与time.sleep初探 大家好 我是寸铁 总结了一篇defer传参与time.sleep初探的文章✨ 喜欢的小伙伴可以点点关注 请大家看下面这段代码看运行结果会出现什么为什么 问题 demo package mainimport (logtime )func main() {start : time.Now()defer func() {log.Printf(匿名函数时间差: %v, time.Since(start))}()defer log.Printf(时间差: %v, time.Since(start))time.Sleep(3 * time.Second)log.Printf(函数结束) }这里不少同学会认为这题我会先输出函数结束待整个函数结束后根据defer后进先出的顺序依次打印计算的时间差由于这里睡眠了3秒两个时间差应该都是3秒左右。 所以答案为 函数结束 时间差3s 匿名函数时间差3s看到这里我想说同学你的思路和想法是好的一开始我也和你一样但是这里的答案是错的那为什么错呢总得有个原因吧很明显匿名函数的时间差符合逻辑是对的那为什么时间差与预期不符合呢下面我来进行分析。 运行结果 分析 这里的关键点在于为什么时间差为0也就是说为什么时间差这个defer语句没有被time.sleep 所影响进一步分析就是查看start的赋值时机在哪是在一开始调用defer就赋值,还是说在函数结束后给defer中的start赋值,从而造成结果的不同。 带着这个问题不妨来debug一下看一下函数语句的执行顺序。 设置断点 要想看一下start的赋值时机设置断点在出现start变量前面即可。 设置好断点后开始进行debug debug查看 step1 一开始先初始化start的值 step2 接着来到第一个defer 匿名函数看它有没有进去里面的printf语句给start变量进行赋值step over 直接跳过了匿名函数的defer语句也就是说明并没有给匿名函数中的defer语句中的start赋值 step3 之后进入defer语句中给time.Since中的start进行赋值。 这里会发现问题的关键所在对比defer 匿名函数 一开始调用(非执行)时不会对里面的变量(参数)start进行赋值。 然而普通的defer printf则在一开始时就会对里面的变量start赋值赋值后不会先把time.since的结果计算出来会在defer调用后也就是光标移动到下一条语句时调用time.sleep计算时间差,其结果就是0s 左右此时不会在调用时输出待整个函数执行完毕退出后依次按照defer 顺序输出。 step4 进一步来到了time.sleep ,这也说明step3 确实给defer 语句赋值了并没有跳过现在开始休眠3 s 观察3s后会光标会去到哪里 猜想3s 后会先输出函数结束 之后函数退出开始执行defer 语句. 结合匿名函数的时间差为3s左右,又因为defer 匿名函数中的start 还未赋值会回到开头的defer 匿名函数进行赋值。 等待3s钟 step5 3s后来到了输出函数结束的语句。 进一步函数退出,也就是整个函数执行完毕 step6 又回到了刚才的defer 匿名函数 果然与step4的猜想一致 关键点来了 如下图这里会进入defer 匿名函数 并给里面的start变量赋值。 注意这里传参start 还是一开始的start 只不过time.since(start) 的time 增加(休眠)了3s 这也很好的解释了为什么defer 匿名函数 输出的是3s 左右,而defer printf 语句却是输出0s 左右。 之后匿名函数结束 退出当前的整个函数 最后整个函数结束,输出debug 的结果 这里加了一些debug 调试的时间以运行结果为准见下。 运行结果如下 探讨 在debug 后我们来探讨一下为什么会出现这样的情况?为什么结果会有所不同里面的机制是什么 defer 输出语句 传值时机一开始调用defer 时传入 Go 语言中所有的函数调用都是传值的 虽然 defer 是关键字但是也继承了这个特性。假设我们想要计算 main 函数运行的时间可能会写出以下的代码 package mainimport (fmttime )func main() {start : time.Now()// 这里误以为startedAt是在time.Sleep之后才会将参数传递给defer所在语句的函数中defer fmt.Println(time.Since(start))time.Sleep(3 * time.Second) }关键点调用defer关键字会立刻拷贝函数中引用的外部参数 所以 time.Since(start) 的结果不是在 main 函数退出之前计算的而是在 defer 关键字调用时赋值计算的最终导致上述代码输出 0s。 defer 匿名函数 传值时机main函数结束后执行defer函数 时传入传入函数指针 package mainimport (fmttime )func main() {start : time.Now()// 使用匿名函数传递的是函数的指针defer func() {fmt.Println(time.Since(start))}()time.Sleep(3 * time.Second) }那为什么使用匿名函数就可以输出3s 呢 关键点defer 使用匿名函数 , 传递的是函数的指针(函数是一种指针类型),结合刚才的断点分析不会在一开始调用defer 匿名函数的时候就直接赋值而是在后面main函数退出时再执行defer 匿名函数 时再传入函数的指针并给start变量赋值。 总结 总而言之一开始调用defer输出语句会进行传值会在调用defer 的时候就直接传递值的拷贝(如刚才的defer输出语句)从而计算时间差。 调用defer 匿名函数 传递的是指针类型(如函数、匿名函数) 会在main函数退出时在执行defer 匿名函数 时再传入函数的指针并给里面的变量赋值。 归根结底是传入的类型不同继而导致传入变量的时机不同造成输出的结果不同 扩展 面试官请你用defer与time.sleep写一个计算函数运行时间的程序 相信看到这里的小伙伴已经很清楚要写什么代码了 package mainimport (fmttime )func main() {start : time.Now()// 使用匿名函数传递的是函数的指针defer func() {fmt.Println(time.Since(start))}()time.Sleep(3 * time.Second) }看到这里的小伙伴恭喜你又掌握了一个知识点 希望大家能取得胜利坚持就是胜利 我是寸铁我们下期再见
http://www.dnsts.com.cn/news/253169.html

相关文章:

  • 绵阳网站关键词网页制作基础教程第一版
  • dw网站建设教程视频营销比较成功的品牌
  • 工商网站备案查询无锡网站优化工作室
  • 网站跟网页的区别wordpress裁剪插件
  • 网站建设论文的中期报告手机vi设计公司
  • 网站群 主要功能公司官网建设
  • 怀柔石家庄网站建设彩页设计多少钱
  • 公司网站后台模板广元建设厅官方网站
  • 我的文档上传到网站 做链接连云港网站建设费用
  • 如何填写网站建设计划表网站加载不出来是什么原因
  • ps做网站广告logo找竞价托管公司
  • 我要建网站需要什么花瓣网网站模板
  • 网站常见问题是什么企业名录是什么
  • 牡丹江商城网站开发设计网站推广联盟
  • 毕业设计做视频网站设计上海做网站seo
  • 酷炫flash网站可以做微积分的网站
  • 安徽建设工程造价信息网站网站没有在工信部备案
  • 在线网站免费网站入口台州城乡建设规划网站
  • 上海建站模板源码wordpress控制台地址
  • 网站建设用到什么学软件去哪个培训机构
  • 广州建设六马路小学网站北京的软件公司集中在哪个区
  • 织梦网站文章发布信息模板下载google 网站收录
  • 个人做网络推广哪个网站好网站的ip地址是什么
  • 单页网站怎么优化网站建设实用教程
  • 国外网站开发现状百度网站结构
  • 羊毛网站建设视频wordpress文库主题
  • 可以做多边形背景的网站装饰公司logo图标图片
  • 广告毕业设计作品网站沈阳软件定制开发公司
  • 建站平台外贸无锡做网站排名
  • 万州网站制作公司wordpress修改网站地址