比方有如下两种例子
第一种写法
function a () {
if ($is_pass_1 ) {
if ($is_pass_2 ) {
if ($is_pass_3 ) {
//...
//业务代码处理
return result;
}
}
}
}
第二种写法
function b () {
if (!$is_pass_1 ) {
//逻辑处理
goto xxxxx;
}
if (!$is_pass_2 ) {
//逻辑处理
goto xxxxx;
}
if (!$is_pass_3 ) {
//逻辑处理
goto xxxxx;
}
//业务代码处理
xxxxxx: #goto 到的位置
// result =
return result
}
之前我可能描述的不清楚, 现在补充下
$is_pass_1, $is_pass_2, $is_pass_3 等不是平级的,自然是不适用 switch
每个判断之后可能都会有部分逻辑处理
if 之后同样存在 else 语句
目前遵循 同一个方法, 只有最后一个出口
业务复杂后,虽然提取了公共的方法, 但依然存在很多 判断组合
我调整后的代码结构
第一种
function a() {
if($is_pass_1) {
//部分逻辑
if($is_pass_2) {
//部分逻辑
if($is_pass_3) {
//...
//业务代码处理
result = 'balbalbalbal';
} else {
//else 逻辑
}
} else {
//else 逻辑
}
} else {
//else 逻辑
}
return result;
}
调整后的第二种写法
function b() {
if(!$is_pass_1) {
//逻辑处理
goto xxxxx;
}
//逻辑处理
if(!$is_pass_2) {
//逻辑处理
goto xxxxx;
}
//逻辑处理
if(!$is_pass_3) {
//逻辑处理
goto xxxxx;
}
//逻辑处理
//业务代码处理
xxxxxx: #goto 到的位置
// result =
return result
}
1
est 2015-09-01 10:32:40 +08:00
php 里难道没有 else if ?
|
2
niinaranpo 2015-09-01 10:32:49 +08:00
为什么不用 switch
|
3
feiyuanqiu 2015-09-01 10:34:44 +08:00
逻辑运算符哭晕在厕所...
function a () { if ($is_pass_1 && $is_pass_2 && $is_pass_3 ) { } } |
4
luban 2015-09-01 10:36:15 +08:00
这 2 段代码不等价,实现功能不一样
|
5
michaelzlies 2015-09-01 10:36:42 +08:00 1
|
7
l1905 OP @feiyuanqiu 每个判断条件后 都会有部分逻辑处理, 上面我可能写的不太清楚
|
8
huijiewei 2015-09-01 10:52:16 +08:00
一个很方便的准则就是
尽早返回。。。 业务逻辑再理一理吧。 goto 这种东西不用也罢 |
9
poorguy 2015-09-01 10:55:42 +08:00
不清楚你具体业务,不过应该可以错误的先退出
```php function b () { if (!$is_pass_1 ) { //不成立的逻辑处理 return; } //成立的逻辑处理 ``` |
10
morefreeze 2015-09-01 11:09:58 +08:00
你可以用
```php do{ if (!$cond1 ) break; if (!$cond2 ) break; while (0 ); ``` 来避免掉 goto ,虽然你现在用 goto 都只是往下跳的,但你不保证之后别人修改你代码会怎么样理解这段呢 |
13
otakustay 2015-09-01 11:17:33 +08:00
公用逻辑抽成另一个函数在各分支里调用就行,别用 goto
|
14
qian19876025 2015-09-01 11:19:43 +08:00
合适就行 为嘛一定要与趋势作对
|
15
alphonsez 2015-09-01 11:26:11 +08:00
goto 挺好的,尤其 C 错误处理的时候。
|
16
ether 2015-09-01 11:50:01 +08:00
function a () {
xxxxxx: #goto 到的位置 // result = return result } function b () { if (!$is_pass_1 ) { //逻辑处理 return a (); } if (!$is_pass_2 ) { //逻辑处理 return a (); } if (!$is_pass_3 ) { //逻辑处理 return a (); } //业务代码处理 xxxxxx: #goto 到的位置 return a (); } |
17
ibremn 2015-09-01 11:52:12 +08:00
|
18
pathletboy 2015-09-01 11:54:47 +08:00
可以用 do while (0 );就别用 goto 了。
|
19
flowfire 2015-09-01 12:16:32 +08:00
@pathletboy do while (0 ) 什么鬼
|
20
ljbha007 2015-09-01 12:21:44 +08:00
switch case 就是为这种情况准备的啊
|
21
FrankFang128 2015-09-01 12:24:26 +08:00
你应该优化逻辑,不要出现这么多 if
|
22
hitmanx 2015-09-01 12:24:29 +08:00 1
想起了 Dijkstra 大神的那篇可能是最著名的文章<Go To Statement Considered Harmful>
|
23
zacard 2015-09-01 12:53:13 +08:00
优化逻辑,优先返回。
|
24
kobe1941 2015-09-01 13:10:38 +08:00
从开始学编程,所有的人包括老师和书籍都不让用 goto
|
25
msg7086 2015-09-01 13:13:58 +08:00
@flowfire do while 0 给你机会用 break 。
另外 Ruby 里推荐的方式是用 throw/catch 来解决。 C++/Java/PHP 的话也可以考虑用这种方法,比较干净。 当然最好的方法肯定是拆函数,只有实在不适合拆函数的时候才考虑 goto 。 |
27
akagi 2015-09-01 13:48:29 +08:00
个人觉得可以试试表驱动?
|
28
21grams 2015-09-01 14:01:02 +08:00
goto 也可以适当的用一下,怕啥,不就是只恐龙嘛。
|
29
msg7086 2015-09-01 14:12:23 +08:00
|
31
l1905 OP @kobe1941 我也"从开始学编程,所有的人包括老师和书籍都不让用 goto" ,但遇到具体业务逻辑的用它的时候, 却没想到强有力不用它的理由,或者说是列不出用 goto 有哪些不能容忍的缺点
|
32
hitmanx 2015-09-01 15:13:38 +08:00 1
@l1905 如果功能简单的话确实没什么。不过假如未来这个函数的功能随着迭代更新变得越来越长,越来越复杂,加之如果后续维护的人并不是当初编写者时,就很容易出各种各样的问题,因为 goto 语句破坏了结构性。即使你现在很清楚你在干什么,也不保证后续模仿你的风格继续增加 goto 语句的人也像你这样清晰,一点小看法。
|
33
iosx 2015-09-01 16:04:50 +08:00
我觉的这个逻辑用 goto 处理很好啊,代码更简洁、更易读。 linux 内核里有很多 goto 啊,尤其是逻辑块多,函数返回前还需要一些处理时,用 goto 很方便。
|
34
computeramber 2015-09-01 16:26:32 +08:00
测试 crawl = =!
|
35
cxbig 2015-09-01 20:31:20 +08:00
goto 在 php 手册里已经明确标注不推荐使用了。
http://php.net/manual/control-structures.goto.php clearPHP: https://github.com/dseguy/clearPHP/blob/master/rules/no-goto.md |
36
twi3325831 2015-09-01 21:40:53 +08:00
楼主试过这种写法没
function b () { do { if (!$is_pass_1 ) { //逻辑处理 break; } //逻辑处理 if (!$is_pass_2 ) { //逻辑处理 break; } //逻辑处理 if (!$is_pass_3 ) { //逻辑处理 break; } //逻辑处理 //业务代码处理 } while (0 ); // 错误处理 // result = return result; } |
37
dorentus 2015-09-01 22:13:30 +08:00
说句题外话, Swift 2 为了支持尽早返回,提供了 guard 关键字来尽早返回,然后提供了 defer 关键字来解决返回导致的无法集中释放资源的问题。
|
38
asj 2015-09-01 22:14:50 +08:00 via iPad
有些时候,看起来似乎今天一个程序员为软件写了 10 行代码,
其实他写了-1000 行代码 |
39
2015813 2015-09-01 22:47:58 +08:00 via Android
大师云:果断 if ,抛弃 goto ,它会让你晕头转向。
|
40
raincious 2015-09-01 23:07:07 +08:00
看了楼主的 Append 之后再看原来的,觉得一二两种方案的区别基本上就是第二种会被打更惨而已……
重构成这样应该就好多了: https://gist.github.com/raincious/c2845e414d62832db861 |
41
cpper 2015-09-01 23:23:01 +08:00 1
对于 if else 这种判断的,请进行读表形式处理。代码大全有类似介绍
|
44
vibbow 2015-09-02 06:14:24 +08:00
try
{ if ( ! aaaa ) { throw new Exception ('aaa'); } if ( ! bbb ) { throw new Exception ('bbb'); } } catch (Exception $e ) { } |
45
flowfire 2015-09-02 06:57:24 +08:00
|
46
zhczhy 2015-09-02 08:21:28 +08:00
允许用 goto 就 goto ,不允许时大部分情况下都可以 do { ... } while (0 )
V2 上还是得多一些这样的纯技术讨论帖 |
47
bdnet 2015-09-02 08:27:02 +08:00
有个叫 switch case
更好的方式可以用字典,如果所用编程语言支持委托的话。 goto 很容易造成死循环 |
50
mcfog 2015-09-02 09:22:02 +08:00
别说 goto 了,我连 else 都不想看到,尤其是一眼看不完的()里的条件或超过 3 行的{}里的代码。战术上提前 return ,抽函数,查表什么的方法有的是,战略上说穿了就是自己其实压根没想清楚就在写代码了,自然写的一手好面条
|
51
Mysdes 2015-09-02 09:36:29 +08:00
在我还是个程序猿的时候,老师千叮咛万嘱咐,如果没人把刀架你脖子上,能别 goto 就别 goto ,哈哈哈
|
52
lizhiqing1996 2015-09-02 09:39:06 +08:00 1
|
53
lizhiqing1996 2015-09-02 09:41:06 +08:00
我怎么看都感觉你的两串代码实现的是不一样的功能,不管是修改前或修改后...
|
54
mornlight 2015-09-02 09:42:52 +08:00
@romisanic 这个很奇怪,许多地方是推荐多用 return 少用嵌套 if else 来明确表示方法结束和返回值,代码可读性更高。
|
55
myv2ex 2015-09-02 10:30:27 +08:00
尝试利用面向对象的思想, 3 个条件非平级,则必定存在引用包含关系,那么可通过定义基本模型关系,再通过接口注入模型对象到处理模型的操作对象,操作对象中根据业务逻辑定义处理各模型的不同逻辑完成继承关系,通过覆写操作取代过程化的代码处理机制,后期随着业务模型对象的增加,也仅仅是完善模型接口定义及方法而已,对今后代码发展具有积极作用。
|
57
soundofu 2015-09-02 13:51:40 +08:00
LZ 的第二种写法作为错误处理的时候也未尝不可,
实际使用中,我采用的更接近 @ibremn 所说的尽早 renturn 。 |
59
Banio 2015-09-02 14:04:48 +08:00
当年学 C 语言的时候 说不推荐用 goto 。。。然后一直我就没用过
|
60
ffffwh 2015-09-02 15:30:26 +08:00
有限状态自动机
|
61
zonghua 2015-09-03 13:41:24 +08:00
javascript 没有 goto,好像也不建议用 switch
|