在TCL中,我们可以这样传递参数吗?
我对在Tcl中传递有关以下代码的参数有疑问:在TCL中,我们可以这样传递参数吗?,tcl,parameter-passing,Tcl,Parameter Passing,我对在Tcl中传递有关以下代码的参数有疑问: set name "Ronaldo" proc GET_PLAYER_INFO {player_id {player_name "$name"}} { global name puts $player_name } 关于上面的代码,我们有一个全局变量“name”,在proc GET_PLAYER_INFO的参数列表中,参数PLAYER_name的默认值设置为“$name”?如果name的值是“罗纳尔多”,它已经是双引号了,我们是否
set name "Ronaldo"
proc GET_PLAYER_INFO {player_id {player_name "$name"}} {
global name
puts $player_name
}
关于上面的代码,我们有一个全局变量“name”,在proc GET_PLAYER_INFO的参数列表中,参数PLAYER_name的默认值设置为“$name”?如果name的值是“罗纳尔多”,它已经是双引号了,我们是否需要在参数列表中像这样添加双引号:player_name“$name”?在我们执行“全局名称”命令之前,player_name的默认值是“罗纳尔多”吗?既然如此,为什么我们需要在程序中使用“全局名称”命令呢?,因为它不能正常工作;
$name
根本不会被计算,因此默认值将是这五个文字字符
如果您在创建过程时绑定默认值,您可以这样做:
proc GET_PLAYER_INFO [list player_id [list player_name $name]] {
...
}
也就是说,proc
的参数只是可以使用Tcl命令和替换构造的普通参数。这是Tcl的一大优点
但是,如果您希望在调用过程时计算该$name
,则必须以不同的方式进行。如果您有某种类型的值永远不会用于播放器名称(例如,空字符串),那么很容易:
proc GET_PLAYER_INFO {player_id {player_name ""}} {
if {$player_name eq ""} {
set player_name $::name
}
...
}
注意,我在这里使用了完全限定的变量名。还有其他方法可以获得该名称(例如,使用global
、使用upvar
、使用variable
、…)
事情变得棘手的地方是你根本没有合适的哨兵值。此时,您必须查看实际提供了多少参数:
proc GET_PLAYER_INFO {player_id {player_name ""}} {
if {[llength [info level 0]] == 2} {
set player_name $::name
}
...
}
命令info level 0
将参数单词的完整列表返回到当前过程调用。这包括GET\u PLAYER\u INFO
本身,在对上述定义的有效调用中,它将是长度为2或3的列表。一旦列表可用,在llength
和数值比较中,检查其长度是一个简单的练习。(不过,使用sentinel值更容易,并且在99.99%的情况下有效。)
最后一个选项是使用特殊的args
formal参数并手动执行解析:
proc GET_PLAYER_INFO args {
if {[llength $args] < 1 || [llength $args] > 2} {
return -code error "wrong # args: should be \"GET_PLAYER_INFO player_id ?player_name?\""
}
set player_id [lindex $args 0]
if {[llength $args] > 1} {
set player_name [lindex $args 1]
} else {
set player_name $::name
}
...
}
proc GET\u PLAYER\u INFO参数{
如果{[llength$args]<1 |[llength$args]>2}{
返回-代码错误“错误”参数:应为“获取球员信息球员id球员姓名”
}
设置玩家id[lindex$args 0]
如果{[llength$args]>1}{
设置玩家名称[lindex$args 1]
}否则{
设置播放器名称$::名称
}
...
}
正如你所看到的,这是相当冗长的