Tcl:列表内的持久增量
Tcl: Persistent increment inside a list
我正在尝试为列表中的每个条目设置多个增量。我以为我可以为每个列表条目分配一个整数...
set list {
{/run 00}
{/run/shm 00}
{/boot 00}
}
并使用以下代码作为 foreach 循环的一部分来增加值...
lset list 1 [expr {[lindex $list 1] + 1}]
我发现该值正确递增,但是当代码第二次和第三次执行时,该值已重置为 00,因此每次传递都不会超过 1。
如果我将标准变量的基本增量设置为代码的一部分..
set counter 00
incr counter
它非常高兴地在每个 运行 代码上递增,并且计数器增加 1,直到我破坏代码。
任何有助于使这项工作正常进行的建议或帮助都将不胜感激。我绝对不是 TCL 专家,所以如果我试图以错误的方式完成此操作,请告诉我。 :)
在此先感谢您的帮助。
我希望这样做 这个:
for {set idx 0} {$idx < [llength $list]} {incr idx} {
lset list $idx 1 [expr {[lindex $list $idx 1] + 1}]
}
会递增该列表中的每个数值,这就是我相信你想要做的。然而,做 这个:
foreach pair $list {
lset pair 1 [expr {[lindex $pair 1] + 1}]
}
不会工作。 Tcl 从概念上将子列表项从 foreach
中的主列表中复制出来,这样对 pair
的更改就不会反映回来。此外,从概念上讲,Tcl 首先也会复制要交给 foreach
的值。当然,这些复制品并不是真的,因为那会非常昂贵!相反,Tcl 使用具有写时复制到共享语义的共享引用,这个系统工作得很好,因为我们可以非常便宜地检查共享状态(这是由 Tcl 的线程模型启用的;值为 never 在线程之间共享,因此共享状态决策可以是无锁的和本地的。
这样做的结果是 Tcl 明确拒绝奇怪的远距离状态更改,这种更改有时会在具有不同语义的语言中导致奇怪的错误。如果您要更改某些内容,它最好是一个变量(因为这些是主要的可变内容),并且当您进行更改时,它就在您面前。
如果你稍微改变你的数据结构使其变平而不是使用成对列表,它就可以用作字典。还有一个 dict incr
命令:
This adds the given increment value (an integer that defaults to 1 if not specified) to the value that the given key maps to in the dictionary value contained in the given variable, writing the resulting dictionary value back to that variable. Non-existent keys are treated as if they map to 0. It is an error to increment a value for an existing key if that value is not an integer. The updated dictionary value is returned.
用法示例:
% set list {/run 0 /run/shm 0 /boot 0}
/run 0 /run/shm 0 /boot 0
% dict incr list /boot
/run 0 /run/shm 0 /boot 1
% puts $list
/run 0 /run/shm 0 /boot 1
如果您想在命令中执行此操作,则必须按名称传递并使用 upvar
,以便在正确的堆栈框架中进行更改:
% proc demo {fstab_} {
upvar 1 $fstab_ fstab
dict incr fstab /run
}
% demo list
/run 1 /run/shm 0 /boot 1
% puts $list
/run 1 /run/shm 0 /boot 1
并更新每个值:
% foreach dir [dict keys $list] { dict incr list $dir }
% puts $list
/run 2 /run/shm 1 /boot 2
我正在尝试为列表中的每个条目设置多个增量。我以为我可以为每个列表条目分配一个整数...
set list {
{/run 00}
{/run/shm 00}
{/boot 00}
}
并使用以下代码作为 foreach 循环的一部分来增加值...
lset list 1 [expr {[lindex $list 1] + 1}]
我发现该值正确递增,但是当代码第二次和第三次执行时,该值已重置为 00,因此每次传递都不会超过 1。
如果我将标准变量的基本增量设置为代码的一部分..
set counter 00
incr counter
它非常高兴地在每个 运行 代码上递增,并且计数器增加 1,直到我破坏代码。
任何有助于使这项工作正常进行的建议或帮助都将不胜感激。我绝对不是 TCL 专家,所以如果我试图以错误的方式完成此操作,请告诉我。 :)
在此先感谢您的帮助。
我希望这样做 这个:
for {set idx 0} {$idx < [llength $list]} {incr idx} {
lset list $idx 1 [expr {[lindex $list $idx 1] + 1}]
}
会递增该列表中的每个数值,这就是我相信你想要做的。然而,做 这个:
foreach pair $list {
lset pair 1 [expr {[lindex $pair 1] + 1}]
}
不会工作。 Tcl 从概念上将子列表项从 foreach
中的主列表中复制出来,这样对 pair
的更改就不会反映回来。此外,从概念上讲,Tcl 首先也会复制要交给 foreach
的值。当然,这些复制品并不是真的,因为那会非常昂贵!相反,Tcl 使用具有写时复制到共享语义的共享引用,这个系统工作得很好,因为我们可以非常便宜地检查共享状态(这是由 Tcl 的线程模型启用的;值为 never 在线程之间共享,因此共享状态决策可以是无锁的和本地的。
这样做的结果是 Tcl 明确拒绝奇怪的远距离状态更改,这种更改有时会在具有不同语义的语言中导致奇怪的错误。如果您要更改某些内容,它最好是一个变量(因为这些是主要的可变内容),并且当您进行更改时,它就在您面前。
如果你稍微改变你的数据结构使其变平而不是使用成对列表,它就可以用作字典。还有一个 dict incr
命令:
This adds the given increment value (an integer that defaults to 1 if not specified) to the value that the given key maps to in the dictionary value contained in the given variable, writing the resulting dictionary value back to that variable. Non-existent keys are treated as if they map to 0. It is an error to increment a value for an existing key if that value is not an integer. The updated dictionary value is returned.
用法示例:
% set list {/run 0 /run/shm 0 /boot 0}
/run 0 /run/shm 0 /boot 0
% dict incr list /boot
/run 0 /run/shm 0 /boot 1
% puts $list
/run 0 /run/shm 0 /boot 1
如果您想在命令中执行此操作,则必须按名称传递并使用 upvar
,以便在正确的堆栈框架中进行更改:
% proc demo {fstab_} {
upvar 1 $fstab_ fstab
dict incr fstab /run
}
% demo list
/run 1 /run/shm 0 /boot 1
% puts $list
/run 1 /run/shm 0 /boot 1
并更新每个值:
% foreach dir [dict keys $list] { dict incr list $dir }
% puts $list
/run 2 /run/shm 1 /boot 2