Go 重定向后停止代码执行

Go 重定向后停止代码执行,go,Go,在调用函数RedirectWithMessage后,我可以知道如何停止执行其余代码吗 将return放在该函数的末尾并没有执行其余代码 我正在寻找Golang中的Php版本的重定向: //main.go func (self *GoodsController) GoodsEditGet(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) tmpID, ok := vars["id"] sess :=

在调用函数
RedirectWithMessage
后,我可以知道如何停止执行其余代码吗

return
放在该函数的末尾并没有执行其余代码

我正在寻找Golang中的Php版本的重定向:

//main.go
func (self *GoodsController) GoodsEditGet(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    tmpID, ok := vars["id"]
    sess := session.Instance(w, r)

    if !ok {
        tpl.Error("Invalid goods id")
    }

    id, _ := strconv.ParseInt(tmpID, 10, 64)

    goods, err := service.NewGoodsService(w, r).GetGoodsDetail(id)

    if err != nil {
        //This utility function will not stop the rest of the code being executed
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }

    //This line will be executed even though the above line producing error
    goodsUom, err := service.NewGoodsService(w, r).GetGoodsUom(id)

    if err != nil {
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }

}

//package utility
func RedirectWithMessage(w http.ResponseWriter, r *http.Request, errMsg string, redirect string) {
    sess := session.Instance(w, r)
    sess.FlashError(errMsg)
    sess.FlashForm(r)
    sess.Save(r, w)
    http.Redirect(w, r, redirect, http.StatusFound)
    return
}
编辑了过度热情否决投票的原因

是的,我完全知道我可以将
return
语句放在调用
RedirectWithMessage
后。我只是不想让我的代码到处都被
return
语句弄得乱七八糟。相反,我只在函数中放了一次。
我只是想知道有没有更好的解决办法?我可以实现与我展示的php代码相同的行为吗

我试图给你一个
恐慌
延迟
的方法,并警告你不要使用它,但后来我意识到更改API可能更好

您可以关注函数的主要逻辑并将错误返回给调用者,并要求调用者以您想要的方式处理错误,例如重定向、日志等

fuunction foo($location){
  header(“Location : $location”);
  exit();
}

 foo("/bar"):
 echo "blah"; //this will not be executed
注1:您可能希望处理更多指定的错误,而不仅仅是处理nil和non-nil。在这种情况下,类型断言可能是一个好主意

注意2:您可能希望包装错误。你可以试试,这是一个由戴夫·切尼(Dave Cheney)编写的处理错误的好软件包


注3:建议不要使用
self
作为接收方名称,因为它非常模糊。

在每次调用
util.RedirectWithMessage
后执行
return
,这就是如何工作的。大多数(如果不是全部的话)错误检查中都应该有一个return语句,或者在遇到问题时(例如:您仍然在使用无效ID)继续执行处理程序。如果您完全知道唯一正确的解决方案:问题是什么?另一种方法是嵌套的if/else语句。你找不到php的
exit
,因为Go一直在运行,它不是一个你可以直接退出的脚本。如果出错,我会添加
nil{handleError();return err}
是惯用的go。
return
不是杂乱。这很有用。它是可读的。这是直截了当的。这是非常必要的。如果你认为写好代码是杂乱无章的,那么我们也没什么可以帮忙的了。是的,我也在考虑恐慌和延迟。我试着在这里问它是否合理。我在函数中加入了redirect,使调用代码变得容易。它可以防止调用代码忘记在调用后加上
return
,从而导致难以跟踪错误。谢谢你的输入。你还想要吗如果
ParseInt
失败(您没有检查)或您的id无效(您没有返回),是否重定向?此解决方案仅在所有错误条件都应产生相同的结果时才有效。@Marc此方法仅处理此问题,但使用类型断言(或值选择)来确定返回的错误,它可以处理多种类型的错误。为True,但在原始错误情况下返回同样简单。虽然你的解决方案确实有效,但我不确定我会推荐它。总的来说,似乎没有什么好的理由试图避免使用
if err{…;return err}
模式。@Marc我想说,原始代码的问题不是避免
return err
,而是错误处理过于冗长。如果出错,则为真
=nil{…}
模式很常见,它在某种程度上使代码多样化。在一个地方处理各种各样的错误将使逻辑更加中心化,在我看来,也更加自动化。
func (self *GoodsController) GoodsEditGet(w http.ResponseWriter, r *http.Request) {
    err:=self.goodsEditGet(w,r)
    if err!=nil { //Note 1
        util.RedirectWithMessage(w, r, err.Error(), "/system/inventory/goods")
    }
}

func (self *GoodsController) goodsEditGet(w http.ResponsWriter, r *http.Request) {
    vars := mux.Vars(r)
    tmpID, ok := vars["id"]
    sess := session.Instance(w, r)

    if !ok {
        tpl.Error("Invalid goods id")
    }

    id, _ := strconv.ParseInt(tmpID, 10, 64)

    goods, err := service.NewGoodsService(w, r).GetGoodsDetail(id)

    if err != nil {
        //This utility function will not stop the rest of the code being executed
        return err //Note 2
    }

    goodsUom, err := service.NewGoodsService(w, r).GetGoodsUom(id)

    if err != nil {
        return err
    }
    return nil
}