列表和字符串 - 有什么细微差别

时间:2014-04-10 16:45:57

标签: tcl

经过一些令人沮丧的调试后,我意识到我对字符串和列表的理解是肤浅的。这是拖延我的代码:

1   set a1 "set a 1"
2    set l1 {}
3    lappend l1 [list $a1]
4    puts "l1=$l1"
5    foreach e $l1 { puts $e; eval $e}

错误在第5行,需要

5    foreach e $l1 { puts $e; set e2 [join $e]; eval $e2}

基本上我需要使用连接将列表转换为字符串,否则eval的脚本是“{set a 1}”而不是“set a 1”。

我在调试期间编写了以下测试脚本:

set li {{set a 1} {set b 2}}
foreach l $li { puts $l; eval $l}

工作正常,我不需要“加入”。

是的,我阅读了有关列表和字符串的在线文档。但仍然无法将双手缠在头上。仍然没有点亮。

你能说清楚吗?我不知道我被困在哪里为什么不能理解差异。

1 个答案:

答案 0 :(得分:2)

嗯,罪魁祸首'在您的初始代码中,您使用的是lappend l1 [list $a1]。你应该得到:

l1={{set a 1}}

当你使用puts "l1=$l1"时,上述意味着你在另一个列表中有一个列表,它本身就在另一个列表中! (打印列表时丢失最外面的大括号)

确实,当您执行[list $a1]时,您正在将包含列表/元素{set a 1}的列表(即{{set a 1}})附加到列表$l1,如果您执行lappend l1 $a1 {1}},您将字符串/列表{set a 1}添加到列表$l1

我认为你真正想要使用的是更像这样的东西:

set a1 [list set a 1]
# Where you get a list containing the 3 elements "set" "a" and "1"
set l1 {}
lappend l1 $a1
foreach e $l1 {puts $e; eval $e}

也许另一种方式来看待它:

set a1 [list set a 1]
puts $a1
# => set a 1

set a1 {set a 1}
puts $a1
# => set a 1

set a [list $a1]
puts $a
# => {set a 1}  -- A list within a list

set l {}
lappend l $a1
puts $l
# => {set a 1}

lappend l $a
puts $l
# => {set a 1} {{set a 1}}
#      list    list in list  -- and $l is the list containing those two.