先描述问题。

最近项目有个需求,数据入库失败后延时一定时间然后重新入库;当失败达到一定次数后就不再进行入库,因为项目简单,也不需要异步处理。所以看到这个问题很容易想到用递归去实现。

我最开始的代码example:

/// <summary>
/// 错误次数
/// </summary>
static int errorCount = ; /// <summary>
/// 测试递归代码
/// </summary>
/// <returns></returns>
static int TestFun()
{
try
{
Console.WriteLine("enter fun ");
int a = ;
int n = / a;
}
catch (Exception ex)
{
if (errorCount >= )
{
Console.WriteLine("number of error==3 bye");
return ;
}
errorCount++;
Thread.Sleep();
TestFun();
}
return ;
}

这个代码我想很多人第一眼看到就很容易想到这个TestFun方法一定返回0,因为除数不能为0 所以一直报错 直到错误大于3 return了。

实际结果应该是1 原因很简单,catch里的return 是递归这个方法中的return。这个时候TestFun并没有全部退出,只是退出了递归的那一层而已。递归退出完了 也就是catch语句块执行完毕后,会继续执行return1。

这个问题本身并不难理解,只是我们都有个固有的思维 方法中return了 就不会执行下面代码了。然后就会忽略下面的递归调用。

说到固有思维我再举个例子还是这个问题。

 /// <summary>
/// 测试递归代码
/// </summary>
/// <returns></returns>
static int TestFun()
{
int result = ;
try
{
Console.WriteLine("enter fun ");
int a = ;
int n = / a;
}
catch (Exception ex)
{
if (errorCount >= )
{
Console.WriteLine("number of error==3 bye");
result = ;
return ;
}
errorCount++;
Thread.Sleep();
TestFun();
}
return result;
}

这个代码 不直接return具体值了,而是将值保存到一个变量里。第一眼看这个代码心想这次应该要返回0了吧,出错后 result已经被赋值0了 这下最后面的return 应该返回1了。

正确结果其实也是返回1。说到底还是因为递归,我们catch 里的result=0 其实是针对当前递归这个方法里面的result。因为我们先递归后改变值的;

我们可以这样去想象:当我一次递归时我们方法是TestFun1 第二次是TestFun2 第三次是 TestFun3  里面的代码还是一样的。所以我catch里面的result其实是对应我TestFun3 里的result。直到我们退出递归回到最初的方法里面即TestFun 时它的result还是1并没有改变。

造成我们直觉上的错误其实就是我一开始说的那种固有思维,代码中变量被赋值后,下面代码没有再操作这个值 那么这个值应该是被修改后的值;当然这种思维在没有递归代码当中肯定是正确的。

当我们递归写的少的情况很容易造成以上那种直觉上的错误判断。

容易忽略的递归当中的return的更多相关文章

  1. python递归中的return"陷阱"

    在做一道练习题(参照下篇博文<在当前目录下递归的查找包含指定字符串的文件>)的时候,发现函数中的return的值竟然是None,百思不得其解,尝试化繁为简,用以下的简单的代码验证了一下 问 ...

  2. 经常犯的错误之递归写不全return

    在写递归函数的时候,只在最后一层写return,中间的过程没有return,导致结果的丢失. 举个例子 LL query(LL i, LL k) { if (sum[i] < k) { ; } ...

  3. python学习笔记之装饰器、递归、算法(第四天)

    参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...

  4. iOS 阶段学习第七天笔记(函数、递归)

     iOS学习(C语言)知识点整理笔记 一.函数 1)概念:具有特定功能的代码块的封装 2)函数的定义: 函数类型+函数名(形参列表) 函数类型 函数名(形参类型1  形参名1,形参类型2   形参名2 ...

  5. Python的递归

    递归 是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象.在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知.使用递归解决问题,思路清晰,代码少.但是在主流高 ...

  6. 递归、尾递归和使用Stream延迟计算优化尾递归

    我们在学数据结构的时候必然会接触栈(Stack),而栈有一个重要的应用是在程序设计语言中实现递归.递归用途十分广泛,比如我们常见的阶乘,如下代码: 1234 public static int (in ...

  7. 傻瓜式理解递归之php递归

    写程序这么久了,有时候别人会问道一些算法比如排序啊,递归啊,总是不知道该怎么去说,今天就来整理一下,让更多的人去傻瓜式的理解递归.递归在网络上有很多定义,但有这么一句话听的最多:递归就是自己调用自己! ...

  8. MyBatis一级缓存引起的无穷递归

    MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...

  9. 算法笔记_017:递归执行顺序的探讨(Java)

    目录 1 问题描述 2 解决方案 2.1 问题化简 2.2 定位输出测试 2.3 回顾总结 1 问题描述 最近两天在思考如何使用蛮力法解决旅行商问题(此问题,说白了就是如何求解n个不同字母的所有不同排 ...

随机推荐

  1. 由于losf引起的pxc启动报错处理

    PXC主节点启动完成后,再启动node1,error日志报错: 2017-05-02T15:23:42.830888Z 0 [ERROR] WSREP: Failed to read 'ready & ...

  2. 从源码来理解slf4j的绑定,以及logback对配置文件的加载

    项目中的日志系统使用的是slf4j + logback.slf4j作为一个简单日志门面,为各种loging APIs(像java.util.logging, logback, log4j)提供一个简单 ...

  3. jmeter IP欺骗功能实现

    使用过loadrunner的同学,应该都了解有个IP欺骗功能,jmeter遇到类似需求怎样实现呢? 环境:windows7,jdk1.8,jmeter3.1 使用IP欺骗功能前提是本地有多个可用IP, ...

  4. 2017 UESTC Training for Data Structures

    http://acm.uestc.edu.cn/#/contest/show/155 对大二来说貌似这套题有点简单了,多是一眼题 发现漏了一题,然而是以前看别人讨论过的:). H:线段树+暴力.大概就 ...

  5. Linux环境下配置JDK,java环境

    1.查看Linux自带的JDK是否已安装 # java -version 2. 查看JDK信息 # rpm -qa | grep java 显示: java-x.x.x-gcj-compat-x.x. ...

  6. 关于Cookie的知识的总结

    Cookie的类型 会话cookie和持久cookie 会话cookie是一种临时cookie,它记录了用户访问站点时的设置和偏好,当用户退出浏览器时,会话cookie就会被删除. 持久cookie的 ...

  7. 开涛spring3(2.3) - IoC的配置使用

    2.3.1  XML配置的结构 一般配置文件结构如下: <beans> <import resource=”resource1.xml”/> <bean id=”bean ...

  8. java集合(4)- java中HashSet详解

    HashSet 的实现 对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,因此 HashSet 的实现比较简单,查看 HashSe ...

  9. VR全景:720全景在线购物点亮你的眼球

    在今天,如果你还不了解什么叫做VR (Virtual Reality),那么你真的就已经Out了.现在的VR,正如当年的智能手机一样,传遍了整个世界,2016年,也被称作VR元年,各种各样的设备,以及 ...

  10. 拥抱Node.js 8.0,N-API入门极简例子

    本文摘录自<Nodejs学习笔记>,更多章节及更新,请访问 github主页地址.欢迎加群交流,群号 197339705. N-API简介 Node.js 8.0 在2017年6月份发布, ...