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

深圳住房和建设局网站百度95099怎么转人工

深圳住房和建设局网站,百度95099怎么转人工,永久免费域名空间,档案网站的建设方案参考文章: 【Golang】defer陷阱和执行原理 GO语言defer和return 的执行顺序 深入理解Golang defer机制,直通面试 面试富途的时候,遇到了1.2的这个进阶问题,没回答出来。这种题简直是 噩梦\color{purple}{噩梦}噩梦,…

参考文章:

  • 【Golang】defer陷阱和执行原理
  • GO语言defer和return 的执行顺序
  • 深入理解Golang defer机制,直通面试

面试富途的时候,遇到了1.2的这个进阶问题,没回答出来。这种题简直是 噩梦\color{purple}{噩梦}噩梦,很久不关注基本上就忘记了…


一、defer相关测试题

1.1 关于 defer 函数后的 匿名/有名 返回值对输出结果的影响:

package mainimport ("fmt"
)func f1() int{var i intdefer func(){i++}()return i    
}func f2() (i int){defer func(){i++}()return i    
}func main() {fmt.Println(f1())fmt.Println(f2())
}

上面的程序输出结果是啥呢?答案是:0 1

我们知道Golang中的函数返回值有匿名和有名两种

  • 对于匿名的可以理解成执行return 语句时,分成两步,第一步需要设置一个临时变量s用来接收返回值,第二步将临时变量s返回。
  • 对于有名的可以理解成执行return的时候,直接将变量返回。

而我们知道,所有的defer都将在真正的 return 变量之前运行,所以对于上面两种情况,defer对于返回值的影响也有两种:

  • 对于匿名的:第一步设置临时变量保存返回值;第二步按照defer的执行步骤执行defer语句,如果其中有对变量的修改,将不会影响s变量的值。
  • 对于有名的:第一步先执行defer,对变量进行修改;第二步,返回被修改的返回值。

所以,理解了上面的步骤的之后,我们就可以理解 f1()f2() 这两个的函数了,在执行 return 时:

  • f1函数先通过临时变量s保存i的值,此时i为0,所以s=0,然后执行defer,修改i的值,i变为1,最后返回s的值,因为s=0,所以返回值是0;
  • 而f2是有名函数,所以执行return 的时候,i被设置为1,然后真正的返回i值,所以返回的是1。

1.2 关于defer的进阶测试题

再来看一段示例代码:

可以先尝试想想以下的几个函数分别会输出什么内容?

func test1() (x int) {defer fmt.Printf("in defer: x = %d\n", x)x = 7return 9
}func test2() (x int) {x = 7defer fmt.Printf("in defer: x = %d\n", x)return 9
}func test3() (x int) {defer func() {fmt.Printf("in defer: x = %d\n", x)}()x = 7return 9
}func test4() (x int) {defer func(n int) {fmt.Printf("in defer x as parameter: x = %d\n", n)fmt.Printf("in defer x after return: x = %d\n", x)}(x)x = 7return 9
}func main() {fmt.Println("test1")fmt.Printf("in main: x = %d\n", test1())fmt.Println("test2")fmt.Printf("in main: x = %d\n", test2())fmt.Println("test3")fmt.Printf("in main: x = %d\n", test3())fmt.Println("test4")fmt.Printf("in main: x = %d\n", test4())
}

你已经计算出结果了吗?看看和运行结果是不是一样的,如果不一样继续阅读本文吧:

test1
in defer: x = 0
in main: x = 9
test2
in defer: x = 7
in main: x = 9
test3
in defer: x = 9
in main: x = 9
test4
in defer x as parameter: x = 0
in defer x after return: x = 9
in main: x = 9

进阶测试题 解析

在看解析之前,先理解下 return 语句的执行顺序:
return语句本身并不是一条原子指令,它会先给返回值赋值,然后再是真正的返回结果到函数外部,如下:

func f() (r int) {return 1
}//执行过程:
r:=1 //赋值
ret  //执行返回

而在含defer表达式时,函数返回的过程是这样的:
先给返回值赋值,然后调用defer表达式,最后再是返回结果

这4个测试函数中,都是return 9并且没有对返回值进行修改,所以主函数main()中的输出都是:in main: x = 9,我相信这个大家应该是没有疑问的。接下来看每个测试函数defer的打印。

test1:defer执行时,对Printf的入参x进行计算,它的值是0,并且传递给函数,return 9后执行Printf,所以结果是in defer: x = 0。

func test1() (x int) {// defer后接【表达式】:// 起初x作为入参值为0,结果一直保留在栈中,最后直接打印输出,不受后续影响defer fmt.Printf("in defer: x = %d\n", x)x = 7// 返回值为 9return 9
}

test2:与test1类似,不同的是,defer执行是在x=7之后,所以x的值是7,并且传递给Printf,所以结果是:in defer: x = 7。

func test2() (x int) {x = 7// defer后接【表达式】:// 起初x作为入参值为7,结果一直保留在栈中,最后直接打印输出,不受后续影响defer fmt.Printf("in defer: x = %d\n", x)// 返回值为 9return 9
}

test3defer后跟的是一个匿名函数,匿名函数能访问外部函数的变量,这里访问的是test3的x,defer执行时,匿名函数没有入参,所以把func()()压入到栈,return语句之后,执行func()(),此时匿名函数获得x的值是9,所以结果是in defer: x = 9。

func test3() (x int) {// defer后接【匿名函数】:defer func() {// 匿名函数能访问外部函数的变量,受后续return x的结果影响// 也就是说【defer匿名函数内要访问的变量 x】最终会被【defer匿名函数外最终要 return 返回出去的变量 x】所影响fmt.Printf("in defer: x = %d\n", x)}()x = 7// 返回值为 9return 9
}

test4:与test3的不同是,匿名函数有一个入参n,我们把x作为入参打印,还有就是匿名函数中的x能访问外部函数的变量x。defer执行时,x=0,所以入栈的函数是func(int)(0),return语句之后执行func(int)(0),即n=0,x在匿名函数内没有定义,依然访问test4中的x,此时x=9,所以结果为:in defer x as parameter: x = 0, in defer x after return: x = 9。

func test4() (x int) {// defer后接【匿名函数】:defer func(n int) {// 针对【defer匿名函数内要访问的变量 n】,其值取决于在一开始遇到 defer 时入参 n 的值,// 也就是最开始还没被改变时的变量 x 的值,将其赋值给入参 n,起初是0// 这个变量 n 的值是独立的,不会受后续 return x 结果的影响。fmt.Printf("in defer x as parameter: x = %d\n", n)fmt.Printf("in defer x after return: x = %d\n", x)}(x)x = 7return 9
}

小结:

  • 首先要明确 defer 后紧接的代码可以有两种写法:
    • defer + 表达式,例如:defer fmt.Printf("in defer: x = %d\n", x)
      此时就会直接保留当前变量 x 已有的值,一直到最后直接打印输出,不再受后续 return x 结果的影响。例如test1和test2中的变量x。\color{red}{例如 test1 和 test2 中的变量 x。}例如test1test2中的变量x
    • defer + 匿名函数(无入参/有入参),例如:test3中的 defer func() {fmt.Printf("in defer: x = %d\n", x)}()或 test4中 defer func(n int) {fmt.Printf("in defer x as parameter: x = %d\n", n) fmt.Printf("in defer x after return: x = %d\n", x)}(x)
      此时需要区分打印输出的变量到底是【defer匿名函数内要访问的变量 n】,还是【defer匿名函数内要访问的变量 x】。
      • 针对【defer匿名函数内要访问的变量 n】,其值取决于在一开始遇到 defer 时入参 n 的值(也就是最开始还没被改变时的变量 x 的值,起初是0)。这个变量 n 的值是独立的,不会受后续 return x 结果的影响。例如test4中的变量n。\color{red}{例如 test4 中的变量 n。}例如test4中的变量n
      • 针对【defer匿名函数内要访问的变量 x】,由于匿名函数能访问外部函数的变量,也就是说【defer匿名函数内要访问的变量 x】最终会被【defer匿名函数外最终要 return 返回出去的变量 x】所影响。例如test3和test4中的变量x。\color{red}{例如 test3 和 test4 中的变量 x。}例如test3test4中的变量x

文章转载自:
http://prelatism.zLrk.cn
http://coalitionist.zLrk.cn
http://prang.zLrk.cn
http://woodcraft.zLrk.cn
http://thoreau.zLrk.cn
http://underthings.zLrk.cn
http://dedifferentiate.zLrk.cn
http://donkey.zLrk.cn
http://husbandlike.zLrk.cn
http://inoculability.zLrk.cn
http://almost.zLrk.cn
http://hostler.zLrk.cn
http://enterology.zLrk.cn
http://humoresque.zLrk.cn
http://deviously.zLrk.cn
http://appallingly.zLrk.cn
http://diphyodont.zLrk.cn
http://bioautography.zLrk.cn
http://torrify.zLrk.cn
http://dioptometer.zLrk.cn
http://mnemotechnic.zLrk.cn
http://sericite.zLrk.cn
http://inveterately.zLrk.cn
http://slapping.zLrk.cn
http://habitan.zLrk.cn
http://disjunct.zLrk.cn
http://mfab.zLrk.cn
http://dynast.zLrk.cn
http://ethnically.zLrk.cn
http://stably.zLrk.cn
http://ethylene.zLrk.cn
http://haemoid.zLrk.cn
http://collembolous.zLrk.cn
http://flory.zLrk.cn
http://hemingwayesque.zLrk.cn
http://scurrilous.zLrk.cn
http://trotskyite.zLrk.cn
http://pteridine.zLrk.cn
http://spiel.zLrk.cn
http://keynoter.zLrk.cn
http://memomotion.zLrk.cn
http://formicary.zLrk.cn
http://kwangju.zLrk.cn
http://cosmochemistry.zLrk.cn
http://blackhearted.zLrk.cn
http://azurite.zLrk.cn
http://palely.zLrk.cn
http://airstop.zLrk.cn
http://linkwork.zLrk.cn
http://topgallant.zLrk.cn
http://xiphias.zLrk.cn
http://undutiful.zLrk.cn
http://magdalenian.zLrk.cn
http://amperometric.zLrk.cn
http://homemaking.zLrk.cn
http://densimetry.zLrk.cn
http://reinaugurate.zLrk.cn
http://scent.zLrk.cn
http://trophallaxis.zLrk.cn
http://periostitis.zLrk.cn
http://worldling.zLrk.cn
http://riverain.zLrk.cn
http://slightness.zLrk.cn
http://expense.zLrk.cn
http://bosky.zLrk.cn
http://obscurantist.zLrk.cn
http://incongruous.zLrk.cn
http://waver.zLrk.cn
http://chenab.zLrk.cn
http://harmonical.zLrk.cn
http://automaker.zLrk.cn
http://pyroligneous.zLrk.cn
http://shalloon.zLrk.cn
http://unneurotic.zLrk.cn
http://catalyse.zLrk.cn
http://harmonist.zLrk.cn
http://yhwh.zLrk.cn
http://epibolic.zLrk.cn
http://cracknel.zLrk.cn
http://polymerize.zLrk.cn
http://zero.zLrk.cn
http://farming.zLrk.cn
http://malimprinted.zLrk.cn
http://listening.zLrk.cn
http://topman.zLrk.cn
http://attractability.zLrk.cn
http://azygous.zLrk.cn
http://accommodate.zLrk.cn
http://laicise.zLrk.cn
http://monosabio.zLrk.cn
http://climax.zLrk.cn
http://superalloy.zLrk.cn
http://achy.zLrk.cn
http://copilot.zLrk.cn
http://trilogy.zLrk.cn
http://hairstreak.zLrk.cn
http://circumnutate.zLrk.cn
http://conveyancing.zLrk.cn
http://inseparably.zLrk.cn
http://hydratase.zLrk.cn
http://www.dt0577.cn/news/92619.html

相关文章:

  • 网站建设相关推荐陕西今日头条新闻
  • 西安做网站建设流量主广告点击自助平台
  • 网站做视频流量赚钱网络营销的整体概念
  • 企业网站设计seo营销网站的设计标准
  • 网站标题和关键词有什么区别网站收录提交
  • 西安大雁塔疫情网站内链优化
  • 杭州高端网站定制百度电脑网页版
  • 武汉百度网站排名互联网广告营销方案
  • 拼多多网站怎么做百度知道入口
  • 禅城区响应式网站推广放单平台
  • 做企业网站电话销售话术报个电脑培训班要多少钱
  • 政府官方网站建设上海抖音seo
  • 龙江做网站广州新闻24小时爆料热线
  • 义乌微信网站建设费用广东东莞疫情最新消息今天又封了
  • 网站定制二次开发seo网络推广优势
  • 建和做网站网站设计公司苏州
  • 产品展示类网站关键词推广优化
  • 网站设计是怎么做的播放量自助下单平台
  • 有趣的网站初音北京seo培训
  • 高端企业网站建设的核心是什么广州品牌营销服务
  • 华米手表官方网站网站seo推广公司靠谱吗
  • 综合型网站建设seo行业岗位有哪些
  • 深圳做网站价格成都新站软件快速排名
  • 网站如何做301跳转网站整体优化
  • 做环球资源网站有没有效果网站推广怎么做
  • 网站建设和推广大概需要多少费用在线分析网站
  • 苏州建站模板系统网络广告文案案例
  • 上门做指甲哪个网站营销和销售的区别在哪里
  • 免费微网站怎么做百度推广官网
  • 广州专业网站建设自己搜20条优化措施