Tcl无法读取变量:没有这样的变量

时间:2013-05-06 21:59:38

标签: tcl ns2

以下代码产生错误:

can't read "n": no such variable
    while executing
"$ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail"
    ("for" body line 2)
    invoked from within
"for {set i 7} {$i < 120} {incr i} {
      $ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}"
    (file "multicast.tcl" line 44)

似乎$ n $ i没有被评估为$ n7等所需格式。解决方案中的任何帮助都非常感谢。

for {set i 0} {$i < 120} {incr i} {
set n$i "[$ns node]"
global n$i
}

# Create links
$ns duplex-link $n0 $n1 1.5Mb 10ms DropTail
$ns duplex-link $n0 $n2 1.5Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.5Mb 10ms DropTail
$ns duplex-link $n2 $n4 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n7 1.5Mb 10ms DropTail
$ns duplex-link $n1 $n5 1.5Mb 10ms DropTail
$ns duplex-link $n4 $n6 1.5Mb 10ms DropTail

#create the rest of the links
for {set i 7} {$i < 120} {incr i} {
      $ns duplex-link $n$i $n([expr ($i+1)%120]) 1Mb 10ms DropTail
}

2 个答案:

答案 0 :(得分:4)

Tcl的$语法不会解析非字母数字变量名称(稍后会出现一些例外),因此它会在$n$i之后停止尝试解析n的第一部分{1}}。这是解析器的限制,但Tcl本身几乎允许任何内容。

其中一个例外是允许使用::命名空间分隔符,另一个例外是您可以在{括号{{1}中放置一个复杂的文字变量名称和}一样。这在这里没有用,因为你不能用这种方式将变量替换成变量名。

你应该做什么

使用数组。形式${n$i}允许在$somename(stuff-to-do-an-index)中进行全范围的替换,除了对括号的一些限制几乎不重要。

stuff-to-do-an-index

其他替代方案

您可以使用global ni; # <-- you might not need this! for {set i 0} {$i < 120} {incr i} { set ni($i) "[$ns node]" } # Create links $ns duplex-link $ni(0) $ni(1) 1.5Mb 10ms DropTail $ns duplex-link $ni(0) $ni(2) 1.5Mb 10ms DropTail $ns duplex-link $ni(2) $ni(3) 1.5Mb 10ms DropTail $ns duplex-link $ni(2) $ni(4) 1.5Mb 10ms DropTail $ns duplex-link $ni(1) $ni(7) 1.5Mb 10ms DropTail $ns duplex-link $ni(1) $ni(5) 1.5Mb 10ms DropTail $ns duplex-link $ni(4) $ni(6) 1.5Mb 10ms DropTail #create the rest of the links for {set i 7} {$i < 120} {incr i} { $ns duplex-link $ni($i) $n([expr ($i+1)%120]) 1Mb 10ms DropTail } 的单参数版本来读取变量(它已被记录,但对于Tcl新手来说有点模糊)。

set

您还可以使用$ns duplex-link [set n$i] $n([expr ($i+1)%120]) 1Mb 10ms DropTail 为变量创建一个别名,然后可以正常操作:

upvar 0

使用upvar 0 n$i myAlias $ns duplex-link $myAlias $n([expr ($i+1)%120]) 1Mb 10ms DropTail

构建这种结构会更加丑陋
subst

之后,真的真的讨厌$ns duplex-link [subst "\$n$i"] $n([expr ($i+1)%120]) 1Mb 10ms DropTail eval(这实际上是有效的:奇怪但是真的!)以及各种类似的东西,但是真的不要那样走阵列非常适合这种事情,真的。

答案 1 :(得分:0)

为清楚起见,我会介绍一些临时变量:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [set $node1] [set $node2] 1Mb 10ms DropTail
}

仅使用单个arg(var的名称)调用set将返回该变量的值。

或者,您可以使用subst命令:

for {set i 7} {$i < 120} {incr i} {
      set node1 n$i
      set node2 n[expr {($i + 1)%120}]
      $ns duplex-link [subst $$node1] [subst $$node2] 1Mb 10ms DropTail
}