goto
is usually considered evil and are discouraged to be used. But sometimes goto
gives a clearer and more readable organization of the code, for example:
I want to do some step by step computation, where the result of each step determines whether the following steps are needed, and if needed, which branch to go. The logic itself is a bit complicated, so there are couple of nested if statements. Assuming goto
was available in python, a neat way to achieve this would be:
do_something
if ...:
goto zero
do_something
if case 1:
do_something
if ...:
goto zero
do_something
elif case 2:
do_something
if ...:
goto zero
do_something
....
result = compute_result(....)
goto next
zero:
result = 0
next:
do_something
Without the help of goto
, it is possible to get the same behavior by introducing boolean variables to store flags and add additional if
tests to turn on or off codes. But this way makes the control flow much less readable. One workaround would be to abuse a one time for
loop to simulate the goto
version of the above code, like below:
zero = True
for _ in range(1):
do_something
if ...:
break
do_something
if case 1:
do_something
if ...:
break
do_something
elif case 2:
do_something
if ...:
break
do_something
....
zero = False
if zero:
result = 0
else
result = compute_result(....)
do_something
My question is, is this the best approach to write a more readable code?
答案 0 :(得分:2)
An easy way to break out of a calculation early is to use an exception:
class ExitCalculation(Exception): pass
try:
do_something
if time_to_goto_zero:
raise ExitCalculation()
do_something
if ...:
do_something
if time_to_go_to_zero:
raise ExitCalculation()
result = compute_result()
except ExitCalculation:
result = 0
do next thing
答案 1 :(得分:2)
Exceptions provide the same type of structured jumps without the implication of repeated execution:
class Foo(Exception):
pass
try:
do_something
if ...:
raise Foo
do_something
if case_1:
do_something
if ...:
raise Foo
do_something
elif case_2:
do_something
if ...:
raise Foo
do_something
except Foo:
result = 0
else:
result = compute_result(...)
Which exception(s) you use are a matter of why your "gotos" break the regular control flow.