【问题标题】:How to make Tcl loop variable exist just within the loop, akin to Perl foreach my如何使 Tcl 循环变量仅存在于循环中,类似于 Perl foreach my
【发布时间】:2016-10-08 09:42:30
【问题描述】:

请参阅下面的 Tcl shell 代码和结果:

% foreach a { 1 2 3 4 5 } { puts $a }
1
2
3
4
5
% puts $a
5

看起来变量 a 留在内存中......例如在 Perl 中可以使用:

foreach my $a

并且 $a 仅在循环期间存在。在 Ruby 中,可以使用闭包:

[1,2,3,4,5].each{|a| puts a.to_s() }

为了达到同样的目的。
在 Tcl 中是否有一种优雅的方法?
谢谢

【问题讨论】:

  • 到目前为止,还没有内置机制。您可以在foreach 循环之后显式使用unset 命令来实现相同的目的。
  • 是的,这就是我现在使用的(杂乱最小化)。
  • 或者,您可以使用rename 覆盖foreach 命令的行为,并为您执行unset 操作。

标签: variables for-loop scope closures tcl


【解决方案1】:

这不是foreach 的当前语义,而且这不太可能在不久的将来改变,因为它会对许多人的现有代码产生严重影响。尤其是目前很多人使用:

foreach {a b c d} $someList break

而不是做:

lassign $someList a b c d

因为那是在 Tcl 8.4 及之前的版本中起作用的,从那以后他们没有更新他们的编码风格。

【讨论】:

    【解决方案2】:

    您可以在闭包内进行迭代:

    apply {vals {foreach a $vals {puts $a}}} {1 2 3 4 5}
    

    或者,您可以将主体设置为参数(在这种情况下,循环变量的名称也应该是参数):

    apply {{varName vals body} {foreach $varName $vals $body}} a {1 2 3 4 5} {puts $a}
    

    如果你把它称为myForeach 什么的,它看起来不那么麻烦:

    set myForeach {{varName vals body} {foreach $varName $vals $body}}
    apply $myForeach a {1 2 3 4 5} {puts $a}
    

    您也可以将其设为解释器宏:

    set myForeach {{varName vals body} {foreach $varName $vals $body}}
    interp alias {} myForeach {} apply $myForeach
    myForeach a {1 2 3 4 5} {puts $a}
    

    文档:applyforeachinterp 包、interpputsset

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-23
      • 2013-02-19
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多