仅在Golang中递归的最外层函数上运行语句
我有一个递归函数,我想要一个只为函数的最外层调用执行一些语句。如何实现此功能仅在Golang中递归的最外层函数上运行语句,go,Go,我有一个递归函数,我想要一个只为函数的最外层调用执行一些语句。如何实现此功能 func fact(n int) int { if n == 0 { return 1 } fact := n * fact(n-1) if outer_most{ fmt.Printf(strconv.Itoa(n)) } return fact } func main() { fact(4) } 这应该只打印对编辑的问题的回答4: 您可以再次使用
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most{
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
这应该只打印对编辑的问题的回答4: 您可以再次使用下面的第二种模式:
func fact(n int, outerMost bool) int {
if n == 0 {
return 1
}
fact := n * fact(n-1, false)
if outerMost {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4, true)
}
同样,您可以使用闭包或助手函数来清理这个问题
原始答复:
尝试使用全局变量:
var outerMost bool = true
func fact(n int) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fact(4)
}
还有其他方法可以实现这一点。例如,您也可以对闭包使用类似的技术。或者将另一个参数添加到事实:
func fact(n int, outerMost bool) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1, outerMost)
}
func main() {
fact(4, true)
}
对已编辑问题的回答:
您可以再次使用下面的第二种模式:
func fact(n int, outerMost bool) int {
if n == 0 {
return 1
}
fact := n * fact(n-1, false)
if outerMost {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4, true)
}
同样,您可以使用闭包或助手函数来清理这个问题
原始答复:
尝试使用全局变量:
var outerMost bool = true
func fact(n int) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fact(4)
}
还有其他方法可以实现这一点。例如,您也可以对闭包使用类似的技术。或者将另一个参数添加到事实:
func fact(n int, outerMost bool) int {
if outerMost {
fmt.Printf(strconv.Itoa(n))
outerMost = false
}
if n == 0 {
return 1
}
return n * fact(n-1, outerMost)
}
func main() {
fact(4, true)
}
您可以传递类似于深度的内容,它在每次调用时递增。例如:
func fact(depth int, n int) int {
if n == 0 {
return 1
}
fact := n * fact(depth + 1, n-1)
if depth == 0 {
fmt.Println(fact) // I assume you meant to print fact here.
}
return fact
}
func main() {
fact(0, 4)
}
如果这真的是您的用例,那么您最好执行以下操作:
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(4))
}
您可以传递类似于深度的内容,它在每次调用时递增。例如:
func fact(depth int, n int) int {
if n == 0 {
return 1
}
fact := n * fact(depth + 1, n-1)
if depth == 0 {
fmt.Println(fact) // I assume you meant to print fact here.
}
return fact
}
func main() {
fact(0, 4)
}
如果这真的是您的用例,那么您最好执行以下操作:
func fact(n int) int {
if n == 0 {
return 1
}
return n * fact(n-1)
}
func main() {
fmt.Println(fact(4))
}
一个简单的匿名函数可能是最干净的,因为它不添加参数,使得外部调用方只需实现内部逻辑的API变得复杂
func fact(n int) int {
var facto func(n int) int
facto = func(n int) int {
if n == 0 {
return 1
}
fact := n * facto(n-1)
return fact
}
n = facto(n)
fmt.Printf("%d", n)
return n
}
这实现了相同的功能,但调用者不必知道如何传递与之无关的额外bool或int值。这里的完整示例:一个简单的匿名函数可能是最干净的,因为它不添加参数,使外部调用方只需实现内部逻辑的API变得复杂
func fact(n int) int {
var facto func(n int) int
facto = func(n int) int {
if n == 0 {
return 1
}
fact := n * facto(n-1)
return fact
}
n = facto(n)
fmt.Printf("%d", n)
return n
}
这实现了相同的功能,但调用者不必知道如何传递与之无关的额外bool或int值。这里的完整示例:回答问题本身:如果出于某种原因,您确实希望运行仅用于最外层func调用的东西,并且不想更改api,那么Golang有一个用于此的运行库。
你可以这样做:
package main
import (
"fmt"
"runtime"
"strconv"
)
func outer_most() bool {
pc:=make([]uintptr,2)
runtime.Callers(2,pc) //skip: 1 - runtime.Caller, 2 - outer_most itself
return runtime.FuncForPC(pc[0])!=runtime.FuncForPC(pc[1]) // test if the caller of the caller is the same func, otherwise it is the outermost
}
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most() {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
游乐场:
这不是一个好的做法,而是最直接地解决问题
注:
使用全局变量很可能会导致故障。您需要在每次调用func时设置它,如果存在一致性,则会涉及数据竞争
如果您不同意每次递归调用都会分配额外的bool参数(这可能需要无数次),您可以查看@Adrian的答案,或者将其包装为bool方法。来回答问题本身:如果出于某种原因,您真的想运行只用于最外层func调用的东西,并且不想更改api,Golang有一个用于此的运行时库。
你可以这样做:
package main
import (
"fmt"
"runtime"
"strconv"
)
func outer_most() bool {
pc:=make([]uintptr,2)
runtime.Callers(2,pc) //skip: 1 - runtime.Caller, 2 - outer_most itself
return runtime.FuncForPC(pc[0])!=runtime.FuncForPC(pc[1]) // test if the caller of the caller is the same func, otherwise it is the outermost
}
func fact(n int) int {
if n == 0 {
return 1
}
fact := n * fact(n-1)
if outer_most() {
fmt.Printf(strconv.Itoa(n))
}
return fact
}
func main() {
fact(4)
}
游乐场:
这不是一个好的做法,而是最直接地解决问题
注:
使用全局变量很可能会导致故障。您需要在每次调用func时设置它,如果存在一致性,则会涉及数据竞争
如果您不同意每次递归调用都会分配额外的bool参数(这可能是无数次的),您可以查看@Adrian的答案,或者将其包装为bool方法。我发布的问题与我需要的不同。很抱歉。请看编辑后的问题。我发布的问题与我需要的不同。很抱歉。请看编辑后的问题。