【发布时间】:2015-03-19 16:57:48
【问题描述】:
鉴于此过程:
proc foo {{aa "a"} {bb "b"} cc} {
echo $cc
}
是否可以调用 proc foo 并仅传递 cc 的值?另外,是否可以通过名称显式地将值传递给cc?
我看到的一切都表明所有参数都必须按位置传递。
【问题讨论】:
标签: tcl
鉴于此过程:
proc foo {{aa "a"} {bb "b"} cc} {
echo $cc
}
是否可以调用 proc foo 并仅传递 cc 的值?另外,是否可以通过名称显式地将值传递给cc?
我看到的一切都表明所有参数都必须按位置传递。
【问题讨论】:
标签: tcl
我会像 Tk 那样做:
proc foo {cc args} {
# following will error if $args is an odd-length list
array set optional [list -aa "default a" -bb "default b" {*}$args]
set aa $optional(-aa)
set bb $optional(-bb)
puts "aa: $aa"
puts "bb: $bb"
puts "cc: $cc"
}
然后
% foo
wrong # args: should be "foo cc ..."
% foo bar
aa: default a
bb: default b
cc: bar
% foo bar -bb hello -aa world
aa: world
bb: hello
cc: bar
【讨论】:
array sets:array set optional {-aa "default a" -bb "default b"}; array set optional $args
过程的参数是按位置传递的。使用两个元素列表作为参数列表的组成部分,例如{aa a},是提供一个默认值。然而,正如手册所说:
具有默认值且后跟非默认参数的参数成为必需参数。在 8.6 中,这将被视为错误。
因此,大多数人设计他们的过程接口以将提供默认值的参数放在参数列表的末尾。
模拟命名参数的一种方法是将过程设计为采用单个参数,该参数是一个字典值,其中字典的键是参数的名称。例如,
proc foo {a} {
if {[dict exists $a cc]} {
puts [dict get $a cc]
}
}
foo [dict create cc "this is the cc argument value"]
如果您不介意确定提供哪些可选参数以及构建字典以调用过程的乏味,那么您可以通过这种方式模拟命名参数,并在为过程提供参数方面获得一定的灵活性。我自己并不经常使用这种技术。我发现更仔细地设计程序界面更容易。但有时情况会导致各种各样的事情发生。
【讨论】:
您可以使用类型闪烁来避免构造 dict..这提供了一个有趣的简单和直观的调用。将 dict 的列表表示形式传递给 proc,例如:
proc foo {a} {
if {[dict exists $a cc]} {
puts [dict get $a cc]
}
}
foo {cc "this is the cc argument value" dd "this is the value of dd}
【讨论】: