Recursion 在变量中重写时的递归

Recursion 在变量中重写时的递归,recursion,go,Recursion,Go,我希望你能帮我,因为这让我很头疼 我正在为中间件创建一个链,之后将执行该链。但它似乎已经成为反复出现。匿名函数中的变量next指向自身 type MiddlewareInterface interface { // Run the middleware for the given request, and receive the next handler. Run(http.ResponseWriter, *http.Request, http.Handler) } creat

我希望你能帮我,因为这让我很头疼

我正在为中间件创建一个链,之后将执行该链。但它似乎已经成为反复出现。匿名函数中的变量
next
指向自身

type MiddlewareInterface interface {
    // Run the middleware for the given request, and receive the next handler.
    Run(http.ResponseWriter, *http.Request, http.Handler)
}

createChain(collection []MiddlewareInterface, handler http.Handler) http.Handler
    next := handler

    for _, middlew := range collection {
        next = func(w http.ResponseWriter, res *http.Request) {
            middlew.Run(w, res, next)
        }
    }

    return next
}

我知道这是一个noob问题,但我真诚地想知道是什么原因导致了这一问题,以及如何解决这一问题。期待您的回答

这似乎是一个循环中的闭包变量问题。您正在创建一个函数,该函数在每个循环中捕获
next
,但这意味着所有函数共享同一个变量
next
,并且它们都具有最后一个循环中留下的值。我认为您可以通过在循环范围内引入一个新的临时变量来修复它:

func createChain(collection []MiddlewareInterface, handler http.Handler) http.Handler
    next := handler

    for _, middlew := range collection {
        thisNext:= next
        mw := middlew
        next = func(w http.ResponseWriter, res *http.Request) {
            mw.Run(w, res, thisNext)
        }
    }

    return next
}

新变量定义的位置可能不太正确,但闭包问题肯定是问题的根源。http中间件处理程序通常不是这样工作的,因为它们通常是相互包装的,而不是相互链接的。

这似乎是循环中的一个闭包变量问题。您正在创建一个函数,该函数在每个循环中捕获
next
,但这意味着所有函数共享同一个变量
next
,并且它们都具有最后一个循环中留下的值。我认为您可以通过在循环范围内引入一个新的临时变量来修复它:

func createChain(collection []MiddlewareInterface, handler http.Handler) http.Handler
    next := handler

    for _, middlew := range collection {
        thisNext:= next
        mw := middlew
        next = func(w http.ResponseWriter, res *http.Request) {
            mw.Run(w, res, thisNext)
        }
    }

    return next
}

新变量定义的位置可能不太正确,但闭包问题肯定是问题的根源。http中间件处理程序通常不是这样工作的,因为它们通常是相互包装的,而不是被链接的。

我觉得我很愚蠢,匿名函数是在创建链之后调用的,这可能是上次设置
next
的值(所以最后一个中间件)。这将始终导致函数指向自身。不是吗?这里只有一个
next
变量。如果每次不重用同一个,那么最终它们的值也不会相同。(我不确定你到底想做什么,因为这段代码无效)我觉得我很愚蠢,匿名函数是在创建链之后调用的,这可能是上次设置
next
的值(所以是最后一个中间件)。这将始终导致函数指向自身。不是吗?这里只有一个
next
变量。如果每次不重用同一个,那么最终它们的值也不会相同。(我不确定你到底想在这里做什么,因为这个代码无效)我想你也必须复制一份
middlew
,因为同样的原因(每次循环都是相同的变量)。你们是英雄的!这是有道理的。在上一次尝试中,我确实复制了
next
变量,没有考虑复制
middlew
。谢谢大家!我想你也必须复制一份middlew的副本,原因是一样的(每次循环都是相同的变量)。你们是英雄的!这是有道理的。在上一次尝试中,我确实复制了
next
变量,没有考虑复制
middlew
。谢谢大家!