有没有一种正确的方法可以“打破” switch 脚本并保留在除了循环之外的过程中?

问题描述 投票:0回答:1

我试图不在不同的开关块中重复相同的代码,并且无法弄清楚除了返回并退出程序之外如何打破开关脚本。

我的问题是,将开关包装在 while 循环中只是为了在需要时中断,这是一件可怕的事情吗?有更好的方法吗?

我花了一段时间,但我意识到中断是不必要的,因为可以在 catch 中设置变量并在其外部进行测试以确定何时运行 opt_2 下的其余代码(如下面的第二个代码示例所示);但休息一下会更清楚,特别是当实际代码比这个示例更复杂时。

谢谢你。

% proc SwitchBreak {condition valid} {
  set ui_state 1
  while { 1 } {
    switch -- $condition {
       opt_1 {
         chan puts stdout opt_1
       } opt_2 {
         chan puts stdout opt_2
         if { [info exists ui_state] && $ui_state == $valid } {
           if { [catch { throw {Database Error} {Failed to Write} } result]} {
             chan puts stdout "${result}. Rolled back"
             set rv 1
             set response {Operation Failed}
             break
           }
         }
         chan puts stdout {Opt_1 code to run only when\
            no valid ui_state or valid state succeeds.}
         set rv 0
         set response {Successful write.}
       } opt_3 {
         chan puts stdout opt_3
       } default {
         chan puts stdout opt_4
       }
    }
    break
  }
  chan puts stdout {Code after the switch.}
  chan puts stdout "rv: $rv; response: $response"
}
% SwitchBreak opt_2 1
opt_2
Failed to Write. Rolled back
Code after the switch.
rv: 1; response: Operation Failed
% SwitchBreak opt_2 0 
opt_2
Opt_1 code to run only when no valid ui_state or valid state succeeds.
Code after the switch.
rv: 0; response: Successful write.

无循环,无中断。

proc SwitchBreak {condition valid} {
  set ui_state 1
    switch -- $condition {
       opt_1 {
         chan puts stdout opt_1
       } opt_2 {
         chan puts stdout opt_2
         set rv 0
         if { [info exists ui_state] && $ui_state == $valid } {
           if { [catch { throw {Database Error} {Failed to Write} } result]} {
             chan puts stdout "${result}. Rolled back"
             set rv 1
             set response {Operation Failed}
           }
         }
         if { $rv == 0 } {
           chan puts stdout {Opt_1 code to run only when\
              no valid ui_state or valid state succeeds.}    
           set response {Successful write.}
         }
       } opt_3 {
         chan puts stdout opt_3
       } default {
         chan puts stdout opt_4
       }
    } 
  chan puts stdout {Code after the switch.}
  chan puts stdout "rv: $rv; response: $response"
}

% % 
% Switch opt_2 1
opt_2
Failed to Write. Rolled back
Code after the switch.
rv: 1; response: Operation Failed
% SwitchBreak opt_2 0
opt_2
Opt_1 code to run only when no valid ui_state or valid state succeeds.
Code after the switch.
rv: 0; response: Successful write.
tcl
1个回答
0
投票

虽然这是合法的,因为你可以编写它并且它会正确执行,但对我来说这看起来非常丑陋;一个简单的

if
...
else
似乎能够表达意图,同时实际上更清晰。我什至可以说我希望这通常是真的。

# Just the bit inside the switch case
chan puts stdout opt_2
if {
    [info exists ui_state] && $ui_state == $valid
    && [catch {
        throw {Database Error} "Failed to Write"
    } result]
} then {
    chan puts stdout "${result}. Rolled back"
    set rv 1
    set response "Operation Failed"
} else {
    chan puts stdout "Opt_1 code to run only when\
        no valid ui_state or valid state succeeds."
    set rv 0
    set response "Successful write."
}

是否存在这样的情况:通过运行一次

while
来完成这个复杂的事情是最好的?我对此表示怀疑...但永远不要说永远。


运行一次

for
会稍微好一点,前提是将
break
放在增量子句中。这样,顶部就更清楚您在做什么。

或者您可以将

try
on break
子句一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.