整齐地将值列在多行中

15

如何在不在每行末尾加反斜杠的情况下列出多行值?

如果没有在每行末尾加反斜杠,就无法创建多行列表。
例如以下(错误的)代码:


如果没有在每行末尾加反斜杠,就无法创建多行列表。 例如以下(错误的)代码:
set pets [list 
    cat
    dog
    elephant
]

产生错误:

invalid command name "cat"
    while executing
"cat"
    invoked from within
"set pets [list
        cat
        dog
        elephant
]"

在行末添加反斜杠即可解决该问题:

set pets [list \
    cat \
    dog \
    elephant \
]

它看起来很丑,而且容易出错。

请注意:

  • 我知道使用花括号({&}),但它不允许执行命令并且仍保留冗余的空格字符。
  • 任何其他命令都可以使用(例如dict create), 不仅仅是我的示例中使用的list

使用Tcl 8.5

3个回答

23

Tcl使用换行符(和分号)作为命令分隔符。这是基本语法的核心部分;你无法绕过它,因此你必须使用双引号或花括号来避免反斜杠病。让我们看看可能性(记住,列表分隔符可以是任何非空白字符序列)。

使用反斜杠的丑陋、容易出错的list

set pets [list \
    cat \
    dog \
    $elephant \
]

花括号中不进行替换

set pets {
    cat
    dog
    $elephant
}

(请注意,在上面的例子中,$elephant 只是一个字符序列,不是可读的变量。)

用双引号进行替换,但要小心!

set pets "
    cat
    dog
    $elephant
"

“Be careful!”的意思是,当你有一个多词成员的列表时,你需要使用内部的[list …]或其他引用:

set pets "
    cat
    dog
    [list $elephant]
    [list "elephant's child"]
"

但是,如果在顶部使用list+反斜杠,这也是正确的。

使用subst...

set pets [subst {
    cat
    dog
    $elephant
    "elephant's child"
}]

我可以通过以下方式“整理一下”(并避免其他潜在问题):

set pets [list {*}[subst {
    cat
    dog
    [list $elephant]
    [list "elephant's child"]
}]]

但是说实话,如果事情变得非常复杂,那么我实际上会这样做:

使用多个命令进行构建

set pets {
    cat
    dog
}
lappend pets $elephant "elephant's child"
没有必要为了使用一个命令而自我折磨,当两个或更多命令可以用更少的问题完成一切时。

2
有时仅将多个换行符附加到文本末尾以分割行也可以使文本排版整齐。
set pets ""
lappend pets cat
lappend pets dog
lappend pets elephant

foreach pet $pets {
   puts "I like to eat ${pet}s"
}

1
这里有一个名为lines的过程,可能符合您的要求——
proc lines {lines} {
    foreach item [uplevel [list subst -nobackslash $lines]] {
        lappend list $item
    }
    return $list
}

这是一个关于它使用的演示 -
set another_pet fish;

set pets [lines {
    cat
    [string range hotdog 3 end]
    elephant
    $another_pet
    "african pygmy hedgehog"
    snapping\ turtle
    "\"henry\" the bengali tiger"
}]

puts $pets

它按照期望的方式输出:
cat dog elephant fish {african pygmy hedgehog} {snapping turtle} {"henry" the bengali tiger}

如果您想尝试一下分支,请点击这里,可以在Ideone上进行。


我会在那里使用 list subst $list 而不是 subst {$list} - Donal Fellows
我编辑了答案,将subst添加了-nobackslash选项,因为这样可以更接近我期望的行为。(更新后的示例反映了这一点。)@DonalFellows,所以完整的代码行应该是foreach item \[[list subst -nobackslash $list]] {,对吗?你是否也出于其他目的而推荐这种风格? - Andrew Cheong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接