Tcl:字符串列表的奇怪行为

Tcl: strange behavior of string list

在下面的代码中,我在 for 循环中生成一个字符串列表,如下所示:

set section 5;
set value 2;
set value_range_new "";
for { set i [expr -$section-1]} {$i <= $section} {incr i} {
  if {$i < [expr -$section]} {
    lappend value_range_new "\<[expr [expr $i+1]*$value]";  
  } elseif {$i == $section} {
    lappend value_range_new "\>[expr $i*$value]";
  } else {
    lappend value_range_new "\[[expr $i*$value]\,[expr [expr $i +1]*$value]\)";
  }
}

然后如果我puts列表出来,结果如下:

<-10 {[-10,-8)} {[-8,-6)} {[-6,-4)} {[-4,-2)} {[-2,0)} {[0,2)} {[2,4)} {[4,6)} {[6,8)} {[8,10)} >10

令人困惑的一点是我不明白 {} 是从哪里来的。如果我像下面这样手动定义列表:

set a "\<-8 \[-8,-6\) \[-6,-4\) ";

看跌结果没有{}。那么我的代码有什么问题,以及如何删除/

在 Tcl 中,您需要知道哪些命令要使用列表,哪些命令要使用字符串。 lappend 是一个列表命令。 puts 接受一个字符串。当您给 puts 一个列表时,Tcl 会将列表转换成它的字符串表示形式。这意味着您会看到一些额外的大括号和反斜杠,以保护具有特殊字符(如 [])的列表元素。

您可以使用 join 命令轻松地将列表转换为字符串。

对于构建字符串,format 命令可以提高可读性。

此外,您不需要接下来的expr命令,使用括号;和 brace your expressions:

set section 5;
set value 2;
set value_range_new "";
for { set i [expr {-$section-1}]} {$i <= $section} {incr i} {
  set this [expr {$i * $value}]
  set next [expr {($i + 1) * $value}]
  if {$i < -$section} {
    lappend value_range_new [format {<%d} $next]  
  } elseif {$i == $section} {
    lappend value_range_new [format {>%d} $this]
  } else {
    lappend value_range_new [format {[%d,%d)} $this $next]
  }
}
puts [join $value_range_new]

产出

<-10 [-10,-8) [-8,-6) [-6,-4) [-4,-2) [-2,0) [0,2) [2,4) [4,6) [6,8) [8,10) >10

算法的较短变体。实际上一个 if 都不需要。

set section 5;
set value 2;
set this [expr {-$section * $value}]
set value_range_new [format {<%d} $this]  
for {set i -$section} {$i < $section} {incr i} {
  lappend value_range_new [format {[%d,%d)} $this [incr this $value]]
}
lappend value_range_new [format {>%d} $this]

puts [join $value_range_new]