V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
roy2220
V2EX  ›  程序员

一个函数只应有一个 return 吗?什么时候应该提前 return,什么时候应该用 else 语句?

  •  
  •   roy2220 · 2018-04-28 23:36:50 +08:00 · 3600 次点击
    这是一个创建于 2182 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个对编码有所追求的人,想必被些问题困扰过。由于这些问题很晦涩,多种写法都是等价的,很少人会把它摆上台面认真的讨论,下面我来分享一下我的思索。

    一个函数只应有一个 return 吗?——即对又错。没有意外情况只应有一个 return,意外情况要提前 return (导致多个 return )。举例:

    students = dict(...)
    
    # 正确的写法
    def get_studen_age(studen_name): # 需求:若学生不存在返回-1
        student = students.get(studen_name, None)
        if student is None: # 意外情况
            return -1
        student.access_count += 1 # 需求:增加访问计数
        return student.age
    
    # 错误的写法[1]
    def get_studen_age(studen_name):
        student = students.get(studen_name, None)
        if student is None: # 意外情况
            return -1 # 错误情况应该尽早返回,代码可读性更佳
        else:
            student.access_count += 1
            return student.age
    
    # 错误的写法[2]
    def get_studen_age(studen_name):
        student = students.get(studen_name, None)
        if student is None: # 意外情况
            student_age = -1 
        else:
            student.access_count += 1
            student_age = student.age
        return student_age # 错上加错,只有一个 return,营造没有错误情况的假象
    

    什么时候应该提前 return,什么时候应该用 else 语句?——正如上面的例子所说,意外情况才要提前 return,否则写在 else 语句里。这又引入了另一个问题:怎么定义意外情况?有一个衡量的方法:if 条件... : [THEN] else [ELSE] 如果在普遍情况下[THEN]部分和[ELSE]部分执行的频度一致,说明没有意外情况,否则[THEN]部分和[ELSE]部分两者中执行频度较低的一方可判定为意外情况(通常为错误处理)。举例:

    # 正确的写法
    def min(a, b):
        if a < b:
            r = a
        else:
            r = b
        # 普遍情况下[r = a]和[r = b]执行的频度(运行的机会)是一致的,这里没有意外情况
        return r
    
    # 错误的写法
    def min(a, b):
        if a < b:
            return a # 这里不该应该是意外
        return b
    
    13 条回复    2018-04-30 15:50:04 +08:00
    crb912
        1
    crb912  
       2018-04-29 02:00:46 +08:00 via Android   ❤️ 1
    任何函数,只有要返回值,都有且仅有一次 return。你虽然前面的代码有多个 return,但处于 if 构建的分支中(有无 else 都一样)。

    我探讨几个问题吧。
    1.你"#错误的写法[1]"和"#正确的写法",这两个例子有区别吗?
    我的看法:
    没任何区别,无非多了一个 else。写不写 else 都可以,纯属看个人爱好。反而,理论上,写 else 代码逻辑更清晰点,别人一目了然。方便粗心的程序员阅读你的代码。所以"错误的写法"真的错误吗?不见得,而且我认为它是一种不错的方式。

    2."错误的写法[2]"又哪里错了吗? 当 if 成立,它立马 return 了错误值-1,难道它没有满足你说的"提前 return"?早知道,此时 else 的语句是不会执行的。
    autoxbc
        2
    autoxbc  
       2018-04-29 09:21:00 +08:00
    卫语句的讨论是周经了,估计又要火一帖
    roy2220
        3
    roy2220  
    OP
       2018-04-29 10:34:23 +08:00 via Android
    @crb912 感谢讨论。每个人对代码可读性的理解不一样,其实这个问题没有的唯一正确的答案。上面所说的"正确"、"错误"并非指功能实现上,而且是风格上的。你指出的第 1 点主要是例子 1 的意外情况只有一个不太明显,如果例子 1 的意外情况很多,都用 if else 的写法,处理正常情况的逻辑会被嵌套得很深,不能一眼找出正常逻辑的部分
    roy2220
        4
    roy2220  
    OP
       2018-04-29 10:41:42 +08:00 via Android
    @crb912 关于你的第二点,其实是我的描述不对,我所定义的"尽早返回"应该是直截了断,不应该留下 else 部分
    crb912
        5
    crb912  
       2018-04-29 11:16:48 +08:00 via Android
    关于要不要 else,我看过书里这么讲的:
    The else isn't needed,but it does help the casual reader understand the intent. —— 《 C++ Primer Plus 》第六版 p308.
    roy2220
        6
    roy2220  
    OP
       2018-04-29 11:32:28 +08:00 via Android
    @crb912 如果真的有一些简单武断的原则,只要竭力去遵守就能写出好代码,那满世界都是优秀程序员了,因为这太简单就能做到了。但现实并不是那么简单,动态地权衡和取舍才能做出好决定,不要盲目地相信各种原则(例如 DRY ?),它们通常都隐含着应用情景,无视应用情景妄想一招鲜,不是懒就是傻
    woscaizi
        7
    woscaizi  
       2018-04-30 10:26:51 +08:00
    实际代码中多个 return 没什么不妥吧,把逻辑处理好就可以。拙见。
    roy2220
        8
    roy2220  
    OP
       2018-04-30 11:10:14 +08:00 via Android
    @woscaizi 光把逻辑写对还不够,可读性很重要,本主题的核心就是 return 与代码的可读性
    woscaizi
        9
    woscaizi  
       2018-04-30 13:13:42 +08:00 via iPhone
    @roy2220 我觉得多个 return 与多个 else 可读性一致。
    roy2220
        10
    roy2220  
    OP
       2018-04-30 13:33:36 +08:00 via Android
    @woscaizi 所以说这本身就是个很主观的问题。本主题的定位人群是认为 return 和 else 可读性不一致、想在两者寻找一个平衡的人,你大可无视本主题,它和你没什么关系
    woscaizi
        11
    woscaizi  
       2018-04-30 13:58:19 +08:00
    @roy2220 #10 你太紧绷了,我只是说出我的观点,而你你只是想找认同你的人。
    roy2220
        12
    roy2220  
    OP
       2018-04-30 14:46:12 +08:00 via Android
    @woscaizi 然而。。。并不是,其实我一开始我就不想回复你(因为觉得没有讨论的共识),但是又怕让你觉得我不太礼貌,只能硬着头皮回复(同时委婉表明我的态度),结果越来越尴尬。。。还是就此打住吧
    woscaizi
        13
    woscaizi  
       2018-04-30 15:50:04 +08:00 via iPhone
    @roy2220 怪我话多。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5343 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 09:05 · PVG 17:05 · LAX 02:05 · JFK 05:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.