如何从proc返回变量

时间:2019-08-07 09:45:17

标签: tcl

我尝试将脚本从perl转换为tcl。 perl脚本运行良好...但是tcl却不行。我认为是因为指针。我不知道如何在tcl中使用指针。您可以更新脚本以正确返回变量吗?。

在tcl脚本中,如果我放$ sofar,它运行良好。但是如果我想像$ perl脚本一样返回$ output作为$ output,它就不能很好地工作。

请帮助我...

#perl script
my @test = &find( 0, [], [], $target, @input );

foreach my $test (@test) {
    print "@{$test}\n";
}

sub find
  {
  my ($sum, $sofar, $output, $want, @numbers ) = @_;
#   print "$sum //// @{$sofar} /// @numbers\n";
  if( $sum == $want )
    {
   # print "@{$sofar}\n";
    push @{$output},$sofar;
    }
  elsif( $sum < $want and @numbers and $numbers[0] > 0 )
    {
    find( $sum + $numbers[0], [ @{$sofar}, $numbers[0] ], $output, $want, @numbers );
    find( $sum, $sofar, $output, $want, @numbers[1..$#numbers] );
    }
    return @{$output};
  }
#tcl script
proc combinationSum {sum sofar want numbers } {
    if { $sum == $want } {
        puts $sofar
        #lappend output $sofar
                         }
    if { ( $sum < $want ) && ( [lindex $numbers 0] > 0 ) && ( [llength $numbers] > 0 ) } {
        combinationSum [expr $sum + [lindex $numbers 0]] [concat $sofar [lindex $numbers 0]] $want $numbers
        combinationSum $sum $sofar $want [lrange $numbers 1 end]
        puts YYY,$sum,$sofar
                                                                                        }
        #return $output
}

set test_input [list 2 3 4 7 8  ]
set test_target 10
set test_output  [ combinationSum 0 [] $test_target $test_input]
puts $test_output

1 个答案:

答案 0 :(得分:2)

要返回列表(或其他任何),只需执行以下操作:

# Returns the contents of a variable; this is cheap as it just does reference shuffling
return $sofar

或:

# A command that produces a list can have that list be returned immediately
return [concat $this $that]

返回的列表可能是副本; Tcl的值在幕后使用了写时复制语义来提高效率。这意味着在脚本级别,语义是只读的,而不必为复制数量的可笑性付出代价。 不是的是远距离操作:如果您想更改某些内容,则必须在那里进行更改或通过变量进行操作。


这将我们带入变量。您可以在调用方中修改变量;这需要使用upvar将调用者的变量纳入范围:

upvar 1 $callersName myName
set myName [thing-to-do-the-update $myName]

按照惯例,您不应在调用方中使用名称,而应始终将变量名称作为过程的参数显式传递。不需要这样做,但是它使处理代码变得更加容易,如果不这样做,则预示着将出现严重的代码问题。