设置一个动态变量。

huangapple go评论43阅读模式
英文:

Setting a dynamic variable

问题

我试图使用,比如说,一个动态变量。

示例:

set i 1
set data_select$i [$txtvar get all]

我得到一个“不存在”的变量错误。

方程的第二部分"[$txtvar get all]"工作正常。

是否有一种方法可以用另一个变量的值来设置一个变量?

英文:

I'm trying to use, lets say, a didynamic namic variable.

Example:

set i 1
set data_select$i [$txtvar get all]

I'm getting a 'doesn't exist' variable error.

The second half of the equation "[$txtvar get all]" is working fine.

is there any way to set a variable with another variable value?

答案1

得分: 2

以下是您要翻译的内容:

有两种标准方法可以实现你所要求的操作,以及一种标准替代方法,虽然不是你所要求的,但当许多人尝试这样做时,它确实满足了他们的需求。

变量命名的变量:upvar

使用upvar创建变量的别名,然后使用简单名称。当变量名称作为参数传递给过程时,这是特别常见的。

proc foo {varName} {
    upvar $varName var
    puts "$varName is $var"
}

foo data_select$i

但是,你可以通过告诉upvar使用可选的级别参数来在当前堆栈帧中创建变量的别名:

upvar 0 data_select$i var
puts "data_select$i is $var"

这样做的缺点是你不能撤销创建这种别名的操作。

变量命名的变量:set

你可以使用set的单参数形式读取变量,其结果是变量的内容:

puts "data_select$i is [set data_select$i]" 

这比使用substeval要好;这些操作需要重新解析内容,并要求你非常小心,但是set保证将其第一个参数用作变量的名称。

变量命名的变量:数组

大多数情况下,当人们提出这个问题时,最好使用关联数组。在这种情况下,它要高效得多。

set i 1
set data_select($i) [$txtvar get all]
puts "the value was $data_select($i)"

这是因为你可以在数组元素的名称中使用替换而不会干扰$用于指示读取的方式。

英文:

There are two standard ways to do what you asked, and one standard replacement that doesn't do what you asked but does do what many people need when they try to do this.

Variable Named Variables: upvar

Make an alias to the variable with upvar, and then use the simple name. This is particularly common when the variable name is passed as an argument to a procedure.

proc foo {varName} {
    upvar $varName var
    puts "$varName is $var"
}

foo data_select$i

However, you can make an alias to a variable in the current stack frame by telling upvar to look there with the optional level argument:

upvar 0 data_select$i var
puts "data_select$i is $var"

The downside of this is you can't undo the making of such aliases.

Variable Named Variables: set

You can read a variable with the one-argument form of set, whose result is the content of the variable:

puts "data_select$i is [set data_select$i]" 

This is superior to using subst or eval; those have to re-parse things and require you to be very careful, but set guarantees that it will use its first argument as the name of a variable.

Variable Named Variables: arrays

Most of the time when people ask this question, they're better off using an associative array. It's much more efficient in this situation.

set i 1
set data_select($i) [$txtvar get all]
puts "the value was $data_select($i)"

This is because you can use substitutions in the name of an array element without disturbing how $ is used to indicate a read.

答案2

得分: 0

可以做到,但有点烦人

$ tclsh
% set i 1
1
% set data_select$i "hello"
hello
% set data_select1              # 变量存在
hello
% set data_select$i             # 你可以使用变量来获取它
hello
% puts $data_select1            # 你可以直接解引用它但是...
hello
% puts $data_select$i
无法读取变量 "data_select": 没有这样的变量
% puts ${data_select$i}
无法读取变量 "data_select$i": 没有这样的变量
% puts [set data_select$i]
hello

Tcl 无法知道它应该首先替换 $i。替换从左到右发生。

使用字典

% set data_select {}
% dict set data_select $i hello
1 hello
% puts [dict get $data_select $i]       # 注意 `$` 用于 data_select
hello
英文:

It can be done, but it's annoying

$ tclsh
% set i 1
1
% set data_select$i "hello"
hello
% set data_select1              # the variable exists
hello
% set data_select$i             # and you can use the var to fetch it
hello
% puts $data_select1            # you can dereference it directly, but ...
hello
% puts $data_select$i
can't read "data_select": no such variable
% puts ${data_select$i}
can't read "data_select$i": no such variable
% puts [set data_select$i]
hello

Tcl has no way to know that it's supposed to substitute $i first. Substitutions occur from left to right.

With a dictionary

% set data_select {}
% dict set data_select $i hello
1 hello
% puts [dict get $data_select $i]       # note the `$` for data_select
hello

答案3

得分: 0

我同意建议使用数组或字典。但如果您绝对需要访问一个变量,其名称必须由其他部分构建,您可以使用upvar命令创建一个别名:

% set i 1
1
% set data_select$i "hello"
hello
% upvar 0 data_select$i var
% puts $var
hello
% set var bye
bye
% puts $data_select1
bye
英文:

I second the advise to use an array or dict. But if you absolutely need to access a variable whose name must be built from other pieces, you can create an alias using the upvar command:

% set i 1
1
% set data_select$i "hello"
hello
% upvar 0 data_select$i var
% puts $var
hello
% set var bye
bye
% puts $data_select1
bye

huangapple
  • 本文由 发表于 2023年5月20日 22:12:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76295657.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定