最新要闻
- 焦点讯息:韩语打不出来_韩语怎么打出来
- 快看点丨魔兽世界免费
- 历史上的多巴胺穿搭:敢穿,敢想,还敢豁得出去 每日时讯
- 2023年海南高考分数线公布:本科批普通类483分
- 苏州治不孕的医院 盆腔炎症的好治疗方法是什么?
- 瑞士水果联盟董事长批评苹果试图获取所有苹果相关知识产权_环球消息
- 天天速看:三亚文旅促消费|有序开展租赁游艇夜航试点
- 环球速讯:探店拉动餐饮消费 合力提振消费信心
- 2天焊完一个节段,京雄大桥这样建 世界动态
- 海南出台常态化监管机制 整治海鲜市场消费欺诈行为_观速讯
- 外交部:美应当停止将新冠病毒溯源问题政治化
- 软件系统、硬件配置将大升级!小米14、小米14 Pro双双现身
- 环球视讯!立即撤销、立即放人!
- 景兴纸业:当前受外部经济大环境影响 包装纸行业并不是特别乐观
- 热点聚焦:要闻:离婚官司第一次的证据在档案第二次能用吗?
- 焦点热议:假“网红”自导自演带货骗局,企业被坑200多万元!
手机
环球观热点:国产EDA软件领域首现深度合作 合见工软与华大九天共推芯片解决方案
【环球新视野】5天一层楼!最新一代“造楼机”亮相武汉
- 环球观热点:国产EDA软件领域首现深度合作 合见工软与华大九天共推芯片解决方案
- 【环球新视野】5天一层楼!最新一代“造楼机”亮相武汉
- 王慧文因健康问题离岗就医 光年之外公司目前正常办公-全球新动态
- 博白:“花样”过端午 品文化大餐
- 突发利空!沪指四连阴AI崩盘,外资抄底内资砸盘,全球高温来袭-每日讯息
- 世界焦点!甘肃省金塔县一卤肉店发生液化气泄漏闪爆起火事件 造成2人轻伤
家电
【天天热闻】go语言递归函数及defer
递归函数
简单来说,递归就是函数自己调用自己。有2种实现方式,一种是直接在自己函数中调用自己,一种是间接在自己函数中调用的其他函数中调用了自己。
递归函数需要有边界条件、递归前进段、递归返回段
(资料图)
递归一定要有边界条件,当边界条件不满足时,递归前进;当边界条件满足时,递归返回
func fib(n int) int { a, b := 1, 1 if n <= 2 && n > 0 { return 1 } else if n <= 0 { return 0 } for i := 2; i < n; i++ { a, b = b, a+b } return b}// 递推公式变递归func fib1(n int) int { switch { case n > 0 && n < 3: return 1 case n == 0: return 0 } return fib1(n-1) + fib1(n-2)}// 循环变递归,循环次数变成了函数调用次数func fib2(a, b, n int) int { if n < 0 { panic("nagetive") } else if n == 0 { return 0 } else if n >= 3 { a, b = b, a+b return fib2(a, b, n-1) } else { return b }}func main() { for i := 0; i < 10; i++ { fmt.Println(fib(i), fib1(i), fib2(1, 1, i)) }}斐波那契数列
在循环层次变成递归函数层次中,n相当于循环变量,b和a+b就是每次循环体中使用的值
递归效率
在上面3个斐波那契数列函数实现中,如果进行时间计算,会发现fib1()函数效率最低,因为其中进行了大量的重复计算,所以慢。fib2()函数采用了递归函数调用层次代替循环层次,效率还不错,和循环版效率差不多。 但是函数每次递归,都会有压栈,递归到最后还要销毁栈帧,也会有资源开销。
对上面fib1函数进行优化后:
func fib(n int) int { a, b := 1, 1 if n <= 2 && n > 0 { return 1 } else if n <= 0 { return 0 } for i := 2; i < n; i++ { a, b = b, a+b } return b}// 递推公式变递归func fib1(n int) int { switch { case n > 0 && n < 3: return 1 case n == 0: return 0 } return fib1(n-1) + fib1(n-2)}func fib11(n int, m map[int]int) int { switch { case n > 0 && n < 3: return 1 case n == 0: return 0 } // 查询map中是否已存在 v, ok := m[n] if ok { return v } else { v = fib11(n-1, m) + fib11(n-2, m) m[n] = v return v }}func fib12(n int, s []int) int { switch { case n > 0 && n < 3: return 1 case n == 0: return 0 } // 查询map中是否已存在 if s[n] != 0 { return s[n] } else { s[n] = fib12(n-1, s) + fib12(n-2, s) return s[n] }}// 循环变递归,循环次数变成了函数调用次数func fib2(a, b, n int) int { if n < 0 { panic("nagetive") } else if n == 0 { return 0 } else if n >= 3 { a, b = b, a+b return fib2(a, b, n-1) } else { return b }}func main() { num := 100000 start_time := time.Now() dig := fib(num) end_time := time.Now() fmt.Printf("%v fib函数用时: %v\n", dig, end_time.Sub(start_time)) // start_time = time.Now() // dig = fib1(num) // end_time = time.Now() // fmt.Printf("%v fib1函数用时: %v\n", dig, end_time.Sub(start_time)) start_time = time.Now() dig = fib2(1, 1, num) end_time = time.Now() fmt.Printf("%v fib2函数用时: %v\n", dig, end_time.Sub(start_time)) start_time = time.Now() m0 := make(map[int]int, 100) dig = fib11(num, m0) end_time = time.Now() fmt.Printf("%v fib11函数用时: %v\n", dig, end_time.Sub(start_time)) start_time = time.Now() s0 := make([]int, num+1, num+1) dig = fib12(num, s0) end_time = time.Now() fmt.Printf("%v fib12函数用时: %v\n", dig, end_time.Sub(start_time))}优化后并对比
当num为100000时,明显看出各个函数哪个效率是最高的了。fib12函数和fib11函数的不同之处是采用的缓存方式不同,由于fib12采用的是切片,fib11采用的是hash表,采用切片,省去了hash计算,节省了很多时间。
间接递归
间接递归调用,是函数通过别的函数调用了自己,这一样也是递归。 只要是递归调用,不管是直接还是间接,都需要注意边界返回问题。但是间接递归调用有时候是非常不明显,代码调用复杂时,很难发现出现了递归调用,这是非常危险的。
func foo() { bar()}func bar() { foo()}foo()
递归是一种很自然的表达,符合逻辑思维
递归相对运行效率低,每一次调用函数都要开辟栈帧
递归有深度限制,如果递归层次太深,函数连续压栈,栈内存就可能溢出了
如果是有限次数的递归,可以使用递归调用,或者使用循环代替,循环代码稍微复杂一些,但是只要不是死循环,可以多次迭代直至算出结果
绝大多数递归,都可以使用循环实现
函数嵌套
package mainimport "fmt"func outer() { c := 99 var inner = func() { fmt.Println("1 inner", c, &c) } inner() fmt.Println("2 outer", c, &c)}func main() { outer()}
到outer中定义了另外一个函数inner,并且调用了inner。outer是包级变量,main可见,可以调 用。而inner是outer中的局部变量,outer中可见。
闭包
自由变量:未在本地作用域中定义的变量。例如定义在内层函数外的外层函数的作用域中的变量。
闭包:就是一个概念,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成了闭包。很多语言都有这个概念,最熟悉就是JavaScript。闭包是运行期动态的概念。
- 函数有嵌套,函数内定义了其它函数
- 内部函数使用了外部函数的局部变量
- 内部函数被返回(非必须)
package mainimport "fmt"func outer() func() { c := 99 fmt.Printf("outer %d %p\n", c, &c) var inner = func() { fmt.Printf("inner %d %p\n", c, &c) } return inner}func main() { var fn = outer() fn()
首先有嵌套函数,也就是有嵌套作用域,inner函数中用到了c,但是它没有定义c,而外部的outer有局部变量c。
代码分析
- 第15行调用outer函数并返回inner函数对象,并使用标识符fn记住了它。outer函数执行完了,其 栈帧上的局部变量应该释放,包括inner函数,因为它也是局部的。但是,c、inner对应的值都不 能释放,因为fn要用。所以这些值不能放在栈上,要放到堆上。在Go语言中,这称为变量逃逸,逃逸到堆上
- 在某个时刻,fn函数调用时,需要用到c,但是其内部没有定义c,它是outer的局部变量,如果这 个c早已随着outer的调用而释放,那么fn函数调用一定出现错误,所以,这个outer的c不能释放, 但是outer已经调用完成了,怎么办?闭包,让inner函数记住自由变量c(逃逸到堆上的内存地址)
defer
defer意思是推迟、延迟。语法很简单,就在正常的语句前加上defer就可以了。
在某函数中使用defer语句,会使得defer后跟的语句进行延迟处理,当该函数即将返回时,或发生 panic时,defer后语句开始执行。
注意os.Exit不是这两种情况,不会执行defer。
同一个函数可以有多个defer语句,依次加入调用栈中(LIFO),函数返回或panic时,从栈顶依次执行 defer后语句。
执行的先后顺序和注册的顺序正好相反,也就是后注册的先执行。 defer后的语句必须是一个函数或方法的调用。
关键词:
【天天热闻】go语言递归函数及defer
今日精选:20亿元!重庆蓝黛科技拟建新能源汽车零部件和触控屏玻璃项目
成都旧货市场回收(二手电动工具旧货市场) 环球看点
百余项促消费活动!长沙暑期文化旅游消费季启动-环球头条
为什么u盘打不开文件(为什么u盘打不开)
世界观点:五年来“最热”端午带动消费市场升温 天津、江苏、重庆等5省销售额超过2019年
环球观热点:国产EDA软件领域首现深度合作 合见工软与华大九天共推芯片解决方案
中国信通院:5月国内市场手机出货量2603.7万部 同比增长25.2%
程雪涛督进全区征迁扫尾工作
焦点讯息:韩语打不出来_韩语怎么打出来
天天观焦点:融合创新与整理优化之路怎么走?看看山力化纤的新型工业化转型
【环球新视野】5天一层楼!最新一代“造楼机”亮相武汉
快看点丨魔兽世界免费
“猪景房”一晚8888元火了?谁在入住?是炒作吗?
历史上的多巴胺穿搭:敢穿,敢想,还敢豁得出去 每日时讯
中英人寿爱心保百万医疗可靠吗?好处有哪些?
焦点观察:黑色家电板块异动下跌 创维数字跌超9%
2023年海南高考分数线公布:本科批普通类483分
火焰纹章Engage章节详情_短讯
悦康药业:拟以1亿元-2亿元回购公司股份|天天快播
小猿搜题查看搜题记录的方法
王慧文因健康问题离岗就医 光年之外公司目前正常办公-全球新动态
博白:“花样”过端午 品文化大餐
【环球时快讯】68家企业获2022年度中央企业改革三年行动重点任务考核A级
原来你是这样的小火锅:自热火锅是如何“自热”的?
今日快看!小学生协助民警铲除大麻,别忘给学校老师点个赞
北京16点55分发布高温黄色预警 全球快报
世界快资讯丨沪深股通|宜安科技6月26日获外资买入0.06%股份
突发利空!沪指四连阴AI崩盘,外资抄底内资砸盘,全球高温来袭-每日讯息
云安区民政局开展端午节期间养老机构安全生产检查工作
热头条丨网红外卖小哥路遇流浪男子 奔波1000公里帮忙将其护送回家
临崖景观揭开神秘面纱 环岛旅游公路正门岭大桥30日通车-消息
世界焦点!甘肃省金塔县一卤肉店发生液化气泄漏闪爆起火事件 造成2人轻伤
观热点:滕州市举办2023年度行政执法人员培训班
2023年天津和平中考成绩查询时间及查分入口
快播:曝iQOO 11S搭载3.2GHz骁龙8 Gen2处理器
《三亚市国土空间规划管理规定》将于7月1日起施行 天天看点
俄罗斯内战 | 国防部长绍伊古首露面,赴俄乌冲突前线视察 时讯
天天微速讯:包头市昆都仑河:碧波潋滟造福民生
世界看点:我县端午助农促消费系列活动精彩呈现
天天快看:山西省阳泉市市场监管综合行政执法队开展夏季餐饮专项检查
到15岁的北京韩美林艺术馆看1864只熊猫
当前速讯:“一辆车”的价格买3居,节日钜惠强势来袭!
杭州萧山开展“护苗”品牌系列活动 热资讯
世界快看:中金基金李亚寅:2023年后半段市场将在震荡中修复 多类风格蕴藏投资机会
规模“失血” 逾两百亿资金撤离货币ETF|世界报道
环球关注:民生银行北京分行扎实开展2023年“守住钱袋子 护好幸福家”防范非法集资宣传月活动
深圳控股拟分拆子公司上市,两天前在深圳卖楼入账 100 亿元 全球观热点
苏州治不孕的医院 盆腔炎症的好治疗方法是什么?
通讯!第12次!巴菲特累计抛售比亚迪超1.2亿股 持股比例不足9%
跨境电商打开格局后该怎么走?-天天时讯
新凤鸣携手桐昆股份 计划启动86.24亿美元印尼北加炼化一体化项目|前沿资讯
回顾经典:4-0淘汰伊藤美诚,陈梦实力确实超一流
身高一米五却名震香港,提拔刘德华、资助周润发,娶漂亮娇妻为妻
成都地铁1号线站点示意图_成都地铁1号线站点-全球今亮点
焦点日报:中国新消费集团(08275)公布年度业绩,净亏2680万港元 同比减少29%
世界百事通!高收益+低回撤,“固收+”爱上“绝对收益”!老牌公募副总:窗口期来了
世界通讯!江苏投管公司增持江苏银行1.05亿股 与江苏信托合并持股10.33%仍为第一大股东
52岁瓦工烈日下施工中暑 医生:防暑有“凉”策
跨境电商成“真、优、美”产品大本营
瑞士水果联盟董事长批评苹果试图获取所有苹果相关知识产权_环球消息
捡到oppo手机怎么解锁锁屏密码视频-捡到oppo手机怎么解锁|世界最资讯
天天头条:湖北咸宁发布3起涉新型毒品犯罪典型案例
天天速看:三亚文旅促消费|有序开展租赁游艇夜航试点
【环球时快讯】长飞光纤光缆(06869)及A轮投资者拟向长飞先进半导体增资合共32.44亿元
【新视野】好消息!万州这些人有购房补贴!快去申报
21健讯Daily|复星凯特CAR-T新适应症获批;合成生物学龙头拟定增募资不超66亿元
苏农银行:黄迅辞去副行长职务
全球时讯:放弃争冠计划,挽留两大核心!无牌可打的76人,只能选择认命
消息!外交部:美应当停止将新冠病毒溯源问题政治化
环球速讯:探店拉动餐饮消费 合力提振消费信心
[统计]长淮治骨科膝关节炎患者做哪些护理?合肥膝关节炎医院排名「点击咨询」
天天有喜2:人间有爱的演员_天天有喜2之人间有爱演员表 全球消息
【话“双圈”聊发展】自贡:主动对接“双核”答好融入成渝发展考卷|环球观焦点
中国石化获浅层常压页岩气突破
国投瑞银基金管理有限公司招聘 国投瑞银基金公司待遇怎么样 全球微动态
2天焊完一个节段,京雄大桥这样建 世界动态
世界今热点:南卡Runner Pro4S实测:骨传导耳机也谈音质,运动、听歌两不误!
做豆豉用酵母粉发酵可以吗?
学生致家长的一封信家长会 世界动态
海南出台常态化监管机制 整治海鲜市场消费欺诈行为_观速讯
王络丹_关于王络丹的介绍
世界最新:5000万等于多少亿(5000万)
多少分可以上湖南科技大学、南华大学、湖南工商大学?
世界滚动:双色球什么时候能买_双色球什么时候开售
外交部:美应当停止将新冠病毒溯源问题政治化
夏天简约舒适的日常穿搭,照着穿就很好看_全球热点
甘肃将迎今年首次暴雨天气过程 防汛办发布预警提示|世界快播
上海市地方金融监管局局长率队赴蚂蚁科技集团调研
鳞皮短嘴贝_关于鳞皮短嘴贝简述 快消息
停息挂账对征信有没有影响?申请停息挂账会影响征信多长时间?
今日热门!6月27日重点数据和大事件前瞻
【BT金融分析师】分析师认为阿里被严重低估,称其增长潜力比想象的大 实时焦点
软件系统、硬件配置将大升级!小米14、小米14 Pro双双现身
世界速讯:主图加水印会降权吗_主图水印在线制作
国防军工行业:航空航天船舶景气高 板块估值匹配度佳
福能东方:正在与政府协商退回重庆机器人产业园项目用地 每日看点
前沿热点:成都翡玥兰庭配建人才公寓周边设施
世界最新:GPT产业联盟成立在即
厦门:461个省市重点项目建设提速