Language agnostic 优雅的处理方式;“不可能”;代码路径

Language agnostic 优雅的处理方式;“不可能”;代码路径,language-agnostic,coding-style,Language Agnostic,Coding Style,有时候,我会遇到这样的情况:我已经编写了一些代码,根据其逻辑,某条路径是不可能的。例如: activeGames = [10, 20, 30] limit = 4 def getBestActiveGameStat(): if not activeGames: return None return max(activeGames) def bah(): if limit == 0: return "Limit is 0" if len(activeGames

有时候,我会遇到这样的情况:我已经编写了一些代码,根据其逻辑,某条路径是不可能的。例如:

activeGames = [10, 20, 30]
limit = 4

def getBestActiveGameStat():
    if not activeGames: return None
    return max(activeGames)

def bah():
    if limit == 0: return "Limit is 0"

    if len(activeGames) >= limit:
        somestat = getBestActiveGameStat()
        if somestat is None:
            print "The universe has exploded"
        #etc...
宇宙爆炸线会发生什么?如果limit为0,则函数返回。如果
len(activeGames)>=limit
,则必须至少有一个活动游戏,因此
getBestActiveGameStat()
不能返回无。那么,我应该检查一下吗

同样的情况也发生在while循环中,它总是在循环中返回:

def hmph():
    while condition:
        if foo: return "yep"
        doStuffToMakeFooTrue()

    raise SingularityFlippedMyBitsError()

因为我“知道”这是不可能的,应该有什么吗?

IMHO,第一个例子更像是一个灾难性故障如何呈现给用户的问题。如果有人做了一些非常愚蠢的事情并将activeGames设置为none,大多数语言都会抛出NullPointer/InvalidReference类型的异常。如果你有一个很好的系统来捕捉这些类型的错误并优雅地处理它们,那么我认为你应该完全忽略这些防护措施

如果你有一套像样的单元测试,它们将非常肯定地确保这种问题不会逃过开发人员的机器

至于第二个问题,你真正要防范的是比赛条件。如果“dostufftomakfootrue()”方法从未使foo为真,该怎么办?这段代码最终会自动运行到地下。我通常会把这样的代码放在计时器上,而不是冒险。如果您的语言有闭包或函数指针(老实说,不太清楚Python…),您可以在一个好的助手方法中隐藏计时逻辑的实现,并以这种方式调用它:

withTiming(hmph, 30) // run for 30 seconds, then fail
如果您没有闭包或函数指针,那么您必须在任何地方都执行此操作:

stopwatch = new Stopwatch(30)
stopwatch.start()
while stopwatch.elapsedTimeInSeconds() < 30
    hmph()
raise OperationTimedOutError()
stopwatch=新秒表(30)
秒表开始
而秒表.elapsedTimeInSeconds()小于30
hmph()
提升操作时间延迟()
如果len(activeGames)>=限制,则 必须至少有一个处于活动状态 游戏,所以getBestActiveGameStat()不能 无返回。那么,我应该检查一下吗 为了它

有时我们会犯错误。您可能现在有一个程序错误,或者有人可能稍后创建一个程序错误

这些错误可能导致异常或单元测试失败。但是调试是昂贵的;有多种方法来检测错误是很有用的

快速编写的assert语句可以对人类读者表示预期的不变量。在调试时,一个失败的断言可以快速地确定错误

Sutter和Alexandrescu在“C++编码标准”中解决了这个问题。尽管有这个标题,他们的论点和指导方针是语言无关的

自由断言以记录内部假设和不变量 ... 使用断言或等效文件自由记录模块内部的假设。。。这必须始终为真,否则表示编程错误


例如,如果
switch
语句中的
default
大小写不能出现,请使用assert(false)添加大小写

啊,python有这两个=)。但是,没有lisp风格的宏。
SingularityLippedMyBitsError的+1。还有一条评论,我经常看到一些程序说“错误:用户不应该看到这个对话框”。确保你的不可能的案例真的不可能!我同意断言是确保其他开发人员知道您没有忘记某些东西的一个很好的方法。对于开关中的默认情况,这也是一种生成错误的有用方法,而不是静默地什么都不做(可能导致灾难性的结果)。不过,我相信这是一种平衡。对于像空引用这样的情况,这是非常常见的,并且无论如何都会抛出错误,这应该是非常明显的,即使是一个简单的断言也会使干净的代码变得不那么干净。在我看来,最重要的事情是确保任何错误都会慢慢出现(断言或其他)为最终用户礼貌处理。:)@Chris Jaynes——一个断言有时会更接近问题的根源。如果选择是显式表达不变量,还是根本不表达它,因为我们没有时间编写一个礼貌的代码来处理我们希望永远不会发生的情况,那么选择应该始终是表达不变量。是的,断言很好。事实上,当我更改某些内容导致意外(对我来说)consequencs=P时,这种“不可能”的代码路径确实发生了。总比默默失败要好!