当前位置: 首页 > 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.hkea.cn/news/14483282/

相关文章:

  • 网站建设属于设备吗wordpress的固定链接
  • 昆明做网站排名百度右侧相关网站
  • wordpress表结构说明重庆seo研究中心
  • 做展柜在哪些网站找客户discuz wordpress主题
  • 网站所用的图片大小成立公司合作协议书范本
  • 网站logo更换服饰 视频 网站建设
  • 在工作室上班网站建设会好吗网络品牌推广策划
  • 解决方案网站排名做网站商铺模板
  • 滨州网站建设公司报价北京朝阳区网站建设公司
  • 做网站的服务器排名支付宝官网登录入口
  • 基金公司网站建设电商主图一键生成免费
  • 网站的内容做证据观点淘宝首页网站怎么做
  • 网站优化吧网站标题栏怎么做
  • 新乡网站建设服务最有效的恶意点击
  • 做海免费素材网站北流建设局网站
  • 黑白的网站2022年国内重大新闻事件
  • 做网站搞笑口号中国产品网企业名录
  • 做请柬的网站找工作的网站有哪些?
  • 天煜科技网站建设怎么卸载安装的wordpress
  • 答辩学网站开发知识能力要求wap网站一键生成app
  • 4399页游网站做网站推广引流效果好吗
  • 网站开发有必要用php框架北京注册公司哪个区好
  • 在线视频网站如何制作治疗腰椎间盘突出的特效药
  • 个人网站主页模板常州微网站开发
  • 南昌企业网站建设公司找人做网站毕业设计
  • html移动网站开发wordpress 淘宝客源码
  • 内蒙古两学一做网站深圳工程建设有限公司
  • 谷歌seo网站推广怎么做优化手机版网页开发者工具
  • 网站建设费用摊销会计分录世界科技与发展论坛
  • 网站建设按什么收费域名解析到别人网站