在编程的过程中, 每个人都有每个人的编程习惯。 就比如在写一个函数的时候, 我就喜欢判断一下不符合预期的接口, 提前报错或者提前返回,这样写下了代码会容易看懂, 没有复杂的嵌套判断。 。
然而还一种习惯,就是习惯统一返回。这样就只有一个地方返回,比较好测试预估。但是相应的,代码的各种判断嵌套可能就比提前返回来的多了,看逻辑会吃力一些。
你觉得呢?
1
jedrek 2017-04-24 11:08:20 +08:00
我觉得这两种并没有好坏之分。我两种都用,主要是看函数里的逻辑情况,捡逻辑最清晰、最易读的方式写
|
2
lany 2017-04-24 11:10:17 +08:00
哪种不费脑用哪种,脑子能不用最好。。。
|
3
murmur 2017-04-24 11:10:41 +08:00
有的时候提前返回可以少写 if/else ,尤其是因为参数不合法的
|
4
sagaxu 2017-04-24 11:12:46 +08:00
|
5
sagaxu 2017-04-24 11:13:19 +08:00
统一返回,是 bad smell
|
6
815lbh 2017-04-24 11:18:20 +08:00
提前返回
|
7
rozbo 2017-04-24 11:18:56 +08:00 1
看起来你们都不写 c 和 c++等手动内存管理的语言啊。
在这种语言中,不能够提前返回,否则可能上面申请的内存忘记释放,或者句柄忘记关闭造成内存泄露或僵尸对象。 当然,即使是自动内存管理的语言,也存在需要手动管理的资源。这个时候提前返回同样可能导致问题的发生。 因此,我建议尽量都使用一个返回语句。除非你确定提前返回不会导致问题的发生。而且,在多人协同工作的时候,不会因为别人在前面加了代码而导致问题的发生。 在我们团队,要求所有人在每个函数或者方法里都有且只能有一个 return 语句。 |
8
huijiewei 2017-04-24 11:19:48 +08:00
提前返回
|
9
coderluan 2017-04-24 11:33:26 +08:00 2
@rozbo
手动管理内存方法很多,可以创建内存池统一管理,可以规定只在构造之后申请内存,或者是提前返回需要特定错误值,你这只是一种解决方法而已,又不是唯一的方法,怎么能看出来别人不写 C++呢,我反而是感觉你 C++写的少。 |
12
rozbo 2017-04-24 11:42:09 +08:00
@coderluan 你说的这几种方案对于你个人来说是可以的,但对于团队成员来说就不是那么容易接受的了,在你提出的这几种方案中,实现成本最小的无疑是约束团队成员用统一的返回方式。
你能保证你团队中没有新手吗? |
13
coderluan 2017-04-24 11:53:07 +08:00
|
18
mkdong 2017-04-24 12:01:13 +08:00 via iPhone
同意 goto ,不仅可以减少不必要的嵌套,还可以统一返回
|
19
0915240 2017-04-24 12:03:59 +08:00 via iPhone
fast failed
|
21
liul85 2017-04-24 12:23:39 +08:00
提前返回 少写 if , else
|
23
chunqiuyiyu 2017-04-24 12:27:23 +08:00 via iPhone
能提前返回就一定要提前返回
|
25
otakustay 2017-04-24 13:01:20 +08:00
使用符合语义的提前返回
|
29
think2011 2017-04-24 13:21:35 +08:00
提前返回,容易看到
|
30
wuethan 2017-04-24 13:30:44 +08:00
封装函数更适合提前返回··· 我喜欢清晰的感觉 无限嵌套思路混乱··· 另外只做过串口和数据库交互 没遇到什么需要关闭的问题,数据库都是一次性的查询完就关 串口就是一直打开做判断即可 条件不足就不执行就完了·· 我是不会在打开和关闭之中写 return;的
|
32
limhiaoing 2017-04-24 13:57:04 +08:00 via iPhone 1
@rozbo
auto a = std::make_unique<char[]>(0x1000); 其实现代 C++不需要手动写任何的 new 和 delete 也能把内存资源管理得很好。 举个例子 https://github.com/lxrite/DawnPlayer 是我写的一个 flv demuxer 涉及到大量的内存分配和释放,但是 C++部分的代码一个 delete 都没有写。 |
33
rozbo 2017-04-24 14:27:53 +08:00
@limhiaoing
@lrxiao @coderluan @gamexg @dingz 提到 c++的内存,统一返回确实不是唯一的解决方案。 但是各种对象具柄怎么办? c 语言怎么办?数据库连接怎么办? 另外我问的是 char * a=(char*) malloc(0x1000);这种怎么办,请正视问题,不要改写这一段。 难道你们写代码的时候,真的是从来不用 malloc ? |
34
limhiaoing 2017-04-24 14:39:46 +08:00 via iPhone
@rozbo
http://en.cppreference.com/w/cpp/memory/unique_ptr sto::unique_ptr 的 deleter 是可定制的,你想释放其他资源定制下 deleter 就可以了。 另外 不明白你是什么需求非得用 malloc 而不能用 std::make_unique 。 |
35
limhiaoing 2017-04-24 14:41:48 +08:00 via iPhone
上面的链接有用 std::unique_ptr 管理文件资源的例子。
|
36
limhiaoing 2017-04-24 14:43:59 +08:00 via iPhone
@rozbo
忘了回答你最后一句了,我写代码确实从来不用 malloc 。 |
37
Ouyangan 2017-04-24 14:50:32 +08:00
java-->遇到要返回的话直接就返回 ,避免后面很多 if 判断
|
38
htfy96 2017-04-24 14:59:36 +08:00
@rozbo
1. 对象句柄封装下 unique_ptr 2. C 本来就是另一种语言 3. 数据库连接也可以啊:参见 https://github.com/cruisercoder/cppstddb/blob/master/src/cppstddb/mysql/database.h#L104 4. auto a = std::unique_ptr<char[]>(new char[0x1000]) 5. 基本不用 |
39
sciooga 2017-04-24 15:10:45 +08:00 via Android
提前返回一般有更好的可读性
|
40
usbuild 2017-04-24 16:04:36 +08:00
C++中不需要 malloc ,甚至有些情况下连 new/delete 都不需要,一般 vector 就够用了。
|
41
jhdxr 2017-04-24 16:07:26 +08:00
php/java: 取决于具体情况,但能够提前返回的时候绝对不会硬拖着到最后再统一返回(例如函数开头的异常情况判断)。
至于资源回收,不熟悉 c++不敢随便说话,但是 php/java 都可以通过 finally 来解决 |
42
Observer42 2017-04-24 16:10:27 +08:00
提前返回,减少嵌套层数,参照 4 楼的
c 没怎么写过, c++有 RAII ,而且自 11 以后 unique_ptr 可以少很多 new/delete ,性能基本不会是问题 |
43
geelaw 2017-04-24 16:13:13 +08:00
……不用 malloc 是不是没写过性能要求高的程序哇……用 vector 的更是,你们很理论计算机科学,常数统统扔掉
@rozbo 这个问题很简单,你可以 char *a = (char *)malloc(0x1000); struct _free_a_tag { char const *ptr; _free_a_tag(char const *p) : ptr{p} { } ~_free_a_tag() { free(ptr); } } _free_a = a; 用得多就 refactor 一个结构到外面去咯。 如果你有一个 handle ,你可以写一个关闭 handle 的类似的玩意儿 |
45
zacard 2017-04-24 16:27:54 +08:00
尽量提前返回
|
46
limhiaoing 2017-04-24 16:27:57 +08:00 via iPhone 2
|
47
jarlyyn 2017-04-24 16:44:36 +08:00
看这个帖子发现 go 的 defer 真是疼程序员
|
48
changwei 2017-04-24 16:47:26 +08:00 via Android
看是写什么代码,像 golang 等语言有 defer 关键词,各种提前返回可能会导致逻辑上的混乱,还是统一返回比较好。毕竟偷懒和优雅二者不可得兼。
|
49
geelaw 2017-04-24 17:13:39 +08:00
@limhiaoing 我应该更正为“只用 new/delete 和 vector<T>”,本意当然不是只能用 malloc ,比如你还可以 calloc ,或者 VirtualAlloc 。
另外如果希望提高 vector 的性能,需要写自己的 allocator (避免愚蠢的 new ,通常的实现),然后调用一次 reserve ,再祈祷编译器可以帮你把那些抽象都返朴归真(好在大多数编译器都可以搞定);反正我是不觉得在性能密集场景下 vector 比脱掉 vector 高明多少——如果要求期间不发生内存重新分配,那 vector 还有什么价值呢? |
50
xiubin 2017-04-24 18:14:36 +08:00
不说使用场景的都是耍流氓吧
判断合法,不合法直接返回 nil : if (para1 == nil) return if (para2 == nil) return if (para3 == nil) return // para ... return ... 根据不同条件会有不同结果: id result; if .. result = .. else if .. result = .. return result |
51
ldp940622 2017-04-24 18:14:54 +08:00
自从使用了 swift ,就比较习惯使用 gurad 和 defer 了
|
53
sagaxu 2017-04-24 18:24:34 +08:00
@changwei 你知道 defer 是干什么用的吗?就是为了提前返回的时候不让你忘记清理工作。有 defer 反而更适合提前返回。
|
54
xiaowangge 2017-04-24 18:53:05 +08:00
游戏行业的表示,一般来说,编码风格都是强制的提前返回 :-)
|
55
bumz 2017-04-24 18:57:12 +08:00
提前返回
|
57
0915240 2017-04-24 20:03:41 +08:00
|
58
orderc 2017-04-24 20:21:25 +08:00 via iPhone
提前返回,不用加一大堆 if else
|
59
mb4555 2017-04-24 20:45:22 +08:00 via Android
提前
|
61
ivvei 2017-04-24 21:09:16 +08:00 via Android
看心情吧…
|
62
shijingshijing 2017-04-24 21:43:40 +08:00
嵌入式里面,这种直接是真值表套状态机的, Guard Clauses 写代码的时候是爽了,测试和 MC/DC 覆盖率分析的时候分分钟教做人。
|
63
kongkongyzt 2017-04-24 22:15:53 +08:00 via Android
提前返回,并且尽量提前返回。
|
64
mingyun 2017-04-24 22:50:33 +08:00
尽早 return
|
65
zoffy 2017-04-24 22:52:23 +08:00
提前
|
66
loveyu 2017-04-25 00:49:47 +08:00
提前吧,至少把错误判断提前,如果觉得复杂就 try_catch ,否则真的很难理解。
|
67
RqPS6rhmP3Nyn3Tm 2017-04-25 05:13:42 +08:00 via iPad
我这里禁止提前返回,因为会要求 proof 。
|
68
MajorAdam 2017-04-25 09:44:10 +08:00
肯定提前
|
69
fanqsh123 2017-04-25 09:56:23 +08:00
int luaGetStringMd5(lua_State* L)
{ int nResult = 0; BOOL bRet = false; char szMd5[64]; const char* pszString = NULL; TRY_GETSTRING(pszString, 1); bRet = GetStringMD5(szMd5, pszString); XYLOG_FAILED_JUMP(bRet); lua_pushstring(L, szMd5); ++nResult; Exit0: return nResult; } goto 挺好用的 |
70
dogfeet 2017-04-25 10:28:38 +08:00
@geelaw 既然都是自己 malloc 了,那操作这块内存的时候大小一定是自己很自信了。实在看不出 vector<uchar> 额定大小再操作 data 比你上面的写法性能低效在哪里,至少肯定不会是比 malloc 低。
|
71
lance26 2017-04-25 10:38:41 +08:00
@shijingshijing 可以给段代码看看吗?想学习下
|
72
wayslog 2017-04-25 12:33:38 +08:00 via Android
@rozbo 看来你不用 RAII 啊…都什么年代了写 C++还手动管理内存?当然了,写 C 的无解了…
|
73
rogerchen 2017-04-25 12:42:34 +08:00 via Android
@wayslog
一看那哥们就是写 C 的,连 C with class 都算不上, RAII 管理外部资源这种常识都不知道。 |
74
allgy 2017-04-25 14:07:03 +08:00
提前返回
|