douzhang5121 2015-01-30 00:10
浏览 34
已采纳

单值上下文中的多个值

Due to error handling in Go, I often end up with multiple values functions. So far, the way I have managed this has been very messy and I am looking for best practices to write cleaner code.

Let's say I have the following function:

type Item struct {
   Value int
   Name string
}

func Get(value int) (Item, error) {
  // some code

  return item, nil
}

How can I assign a new variable to item.Value elegantly. Before introducing the error handling, my function just returned item and I could simply do this:

val := Get(1).Value

Now I do this:

item, _ := Get(1)
val := item.Value

Isn't there a way to access directly the first returned variable?

  • 写回答

5条回答 默认 最新

  • duanjitong7226 2015-01-30 09:49
    关注

    In case of a multi-value return function you can't refer to fields or methods of a specific value of the result when calling the function.

    And if one of them is an error, it's there for a reason (which is the function might fail) and you should not bypass it because if you do, your subsequent code might also fail miserably (e.g. resulting in runtime panic).

    However there might be situations where you know the code will not fail in any circumstances. In these cases you can provide a helper function (or method) which will discard the error (or raise a runtime panic if it still occurs).
    This can be the case if you provide the input values for a function from code, and you know they work.
    Great examples of this are the template and regexp packages: if you provide a valid template or regexp at compile time, you can be sure they can always be parsed without errors at runtime. For this reason the template package provides the Must(t *Template, err error) *Template function and the regexp package provides the MustCompile(str string) *Regexp function: they don't return errors because their intended use is where the input is guaranteed to be valid.

    Examples:

    // "text" is a valid template, parsing it will not fail
    var t = template.Must(template.New("name").Parse("text"))
    
    // `^[a-z]+\[[0-9]+\]$` is a valid regexp, always compiles
    var validID = regexp.MustCompile(`^[a-z]+\[[0-9]+\]$`)
    

    Back to your case

    IF you can be certain Get() will not produce error for certain input values, you can create a helper Must() function which would not return the error but raise a runtime panic if it still occurs:

    func Must(i Item, err error) Item {
        if err != nil {
            panic(err)
        }
        return i
    }
    

    But you should not use this in all cases, just when you're sure it succeeds. Usage:

    val := Must(Get(1)).Value
    

    Alternative / Simplification

    You can even simplify it further if you incorporate the Get() call into your helper function, let's call it MustGet:

    func MustGet(value int) Item {
        i, err := Get(value)
        if err != nil {
            panic(err)
        }
        return i
    }
    

    Usage:

    val := MustGet(1).Value
    

    See some interesting / related questions:

    how to parse multiple returns in golang

    Return map like 'ok' in Golang on normal functions

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料