Recursion 无显式返回的递归TCL过程

Recursion 无显式返回的递归TCL过程,recursion,tcl,Recursion,Tcl,我正在写一个简单的“过程”来计算阶乘。我想理解为什么没有return语句我的函数就不能工作 根据TCL文档,没有明确“返回”定义的函数, 返回其主体中最后执行的命令的值 proc fac { n } { if { $n == 1 } { return 1 } puts $n set n [expr {$n - 1}] return [expr {[fac $n ] * $n}]

我正在写一个简单的“过程”来计算阶乘。我想理解为什么没有return语句我的函数就不能工作

根据TCL文档,没有明确“返回”定义的函数, 返回其主体中最后执行的命令的值

    proc fac { n } {
       if { $n == 1 } {
         return 1
       } 
    puts $n
    set n [expr {$n - 1}]
    return [expr {[fac $n ] * $n}]                                                                                                                                                            
    }
    puts [fac 5] # ans 24
删除“return”后,我会收到以下错误消息:

    invalid command name "1"
      while executing
     "[expr {[fac $n ] * $n}] "
        (procedure "fac" line 7)
        invoked from within

我希望如果没有显式的“return”,函数也应该返回24。

您的期望是正确的。但最后一行中的
expr
过程周围有方括号。它是:

[expr {[fac $n] * $n}]
这对于解释器意味着:1)使用给定参数执行
expr
过程;2) 执行
expr
过程的结果。因此,解释器尝试执行不存在的过程
1
,您将收到一个错误

要修复此错误,只需从最后一行中删除方括号:

proc fac { n } {
   if { $n == 1 } {
     return 1
   } 
   puts $n
   set n [expr {$n - 1}]
   expr {[fac $n ] * $n}                                                                                                                                                           
}

你的期望是正确的。但最后一行中的
expr
过程周围有方括号。它是:

[expr {[fac $n] * $n}]
这对于解释器意味着:1)使用给定参数执行
expr
过程;2) 执行
expr
过程的结果。因此,解释器尝试执行不存在的过程
1
,您将收到一个错误

要修复此错误,只需从最后一行中删除方括号:

proc fac { n } {
   if { $n == 1 } {
     return 1
   } 
   puts $n
   set n [expr {$n - 1}]
   expr {[fac $n ] * $n}                                                                                                                                                           
}

谢谢你的回答。然而,我不清楚为什么它与“return”一起工作。为什么在这种情况下,解释器不再尝试执行[1]?解释器使用第一个单词作为命令名。Return是一个接受参数的命令,其中一个参数可以是希望作为过程值返回的值。在您的例子中,您给出的参数是执行expr命令的返回值。expr命令、其参数和括号被expr命令本身的执行结果替换。在没有任何显式返回命令的情况下,过程返回最后执行的命令的值。这就是为什么朴素的expr命令有效。谢谢你的回答。然而,我不清楚为什么它与“return”一起工作。为什么在这种情况下,解释器不再尝试执行[1]?解释器使用第一个单词作为命令名。Return是一个接受参数的命令,其中一个参数可以是希望作为过程值返回的值。在您的例子中,您给出的参数是执行expr命令的返回值。expr命令、其参数和括号被expr命令本身的执行结果替换。在没有任何显式返回命令的情况下,过程返回最后执行的命令的值。这就是朴素的expr命令工作的原因。您认为
5!==24
?这并不能回答您的问题,但它可以这样实现:
proc::tcl::mathfunc::fac{n}{expr{$n==1?1:$n*fac($n-1)}
然后
expr{fac(6)}
您的程序不会在tcl 8.5或8.6上返回任何错误。。。只是你计算阶乘的方法不正确。你为什么认为
5!==24
?这并不能回答您的问题,但它可以这样实现:
proc::tcl::mathfunc::fac{n}{expr{$n==1?1:$n*fac($n-1)}
然后
expr{fac(6)}
您的程序不会在tcl 8.5或8.6上返回任何错误。。。只是你计算阶乘的方法不正确。