爱丽丝
发布于

Golang异常处理

Golang中对于异常的处理通常是返回Error的形式。 假设我需要封装http Response返回,代码可能会是如下情况

type Header struct{
    Key,Value string
}
type Status struct{
    Code int
    Message string
}
func Response(w io.Writer,status Status, headers []Header, body io.Reader) error {
    _,err:=fmt.Fprintf(w, "HTTP/1.1 %d %s\r\n", status.Code,status.Message)
    if err!=nil{
        return err
    }
    for _,header:=range headers{
        _,err=fmt.Fprintf(w,"%s: %s\r\n",header.Key,header.Value)
        if err!=nil{
            return err
        }
    }
    _,err=fmt.Fprint(w,"\r\n")
    if err!=nil{
        return err
    }
    _,err=io.Copy(w,body)
    if err!=nil{
        return err
    }
    return nil
}

可以看到通篇都充斥着if err!=null的判断,看着很不优雅。 对于这种情况可以考虑用以下方式改变代码使其变得优雅。

type Header struct {
    Key, Value string
}
type Status struct {
    Code    int
    Message string
}
type errWriter struct {
    w   io.Writer
    err error
}

func (ew *errWriter) Write(bytes []byte) (int, error) {
    if ew.err != nil {
        return -1, ew.err
    }
    n,err:=ew.w.Write(bytes)
    ew.err=err
    return n,err
}

func Response(w io.Writer, status Status, headers []Header, body io.Reader) error {
    ew := &errWriter{w, nil}
    fmt.Fprintf(ew, "HTTP/1.1 %d %s\r\n", status.Code, status.Message)
    for _, header := range headers {
        fmt.Fprintf(ew, "%s: %s\r\n", header.Key, header.Value)
    }
    io.Copy(ew, body)
    return ew.err
}
浏览 (172)
点赞 (1)
收藏
评论
暂无数据