单值上下文中的多个值

2024-03-19

由于 Go 中的错误处理,我经常会得到多个值函数。到目前为止,我管理此问题的方式非常混乱,我正在寻找最佳实践来编写更清晰的代码。

假设我有以下功能:

type Item struct {
   Value int
   Name string
}

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

  return item, nil
}

如何将新变量分配给item.Value优雅地。在介绍错误处理之前,我的函数刚刚返回item我可以简单地这样做:

val := Get(1).Value

现在我这样做:

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

有没有办法直接访问第一个返回的变量?


如果是多值返回函数,则在调用该函数时无法引用结果的特定值的字段或方法。

如果其中一个是error,它在那里是为了reason(这是函数might失败)你应该not绕过它,因为如果你这样做,你的后续代码might也会严重失败(例如导致运行时恐慌)。

然而,在某些情况下您可能know该代码在任何情况下都不会失败。在这些情况下,您可以提供helper函数(或方法)将丢弃error(或者如果仍然发生,则引发运行时恐慌)。
如果您通过代码为函数提供输入值,并且您知道它们可以工作,则可能会出现这种情况。
很好的例子是template http://golang.org/pkg/text/template/ and regexp http://golang.org/pkg/regexp/包:如果您在编译时提供有效的模板或正则表达式,则可以确保它们始终可以在运行时被解析而不会出现错误。为此template包提供了Must(t *Template, err error) *Template http://golang.org/pkg/text/template/#Must函数和regexp包提供了MustCompile(str string) *Regexp http://golang.org/pkg/regexp/#MustCompile功能:他们不返回error因为它们的预期用途是保证输入有效。

例子:

// "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]+\]$`)

回到你的案例

IF你可以确定Get()不会产生error对于某些输入值,您可以创建一个助手Must()不会返回的函数error但如果仍然发生,则会引发运行时恐慌:

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

但您不应该在所有情况下都使用此方法,除非您确信它会成功。用法:

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

Go 1.18 泛型更新:Go 1.18 添加了泛型支持,现在可以编写泛型Must()功能:

func Must[T any](v T, err error) T {
    if err != nil {
        panic(err)
    }
    return v
}

这可以在github.com/icza/gog https://pkg.go.dev/github.com/icza/gog, as gog.Must() https://pkg.go.dev/github.com/icza/gog#Must(披露:我是作者)。

替代/简化

如果您合并,您甚至可以进一步简化它Get()调用你的辅助函数,让我们调用它MustGet:

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

Usage:

val := MustGet(1).Value

查看一些有趣/相关的问题:

如何将多个返回值传递给可变参数函数? https://stackoverflow.com/questions/52653779/how-to-parse-multiple-returns-in-golang/52654950#52654950

在普通函数上返回 Golang 中类似“ok”的映射 https://stackoverflow.com/questions/28487036/return-map-like-ok-in-golang-on-normal-functions/28487270#28487270

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单值上下文中的多个值 的相关文章

随机推荐

  • 如何获取 TensorFlow 中估算器的默认会话?

    我创建了一个估算器并使用估算器将其导出到 SavedModel 文件export savedmodel 功能 出于可重复性的原因 我希望能够重新创建估算器 加载 SavedModel 文件中的变量 然后调用evaluate 并得到相同的结果
  • 在启用 SuperTab 的情况下,如何使用 Tab 键在 vim 中缩进?

    我刚刚在 vim 中启用了 SuperTab 如果我尝试缩进空行 SuperTab 会尝试插入字符串 我想 我想要的是让 SuperTab 提供补全功能only如果光标左侧有非空白 我不想使用 Ctrl V 或 Ctrl Q 或其他任何东西
  • 测量 x86-64 中的 TLB 未命中处理成本

    我想估计运行 Linux 的 x86 64 Intel Nehalem 计算机上由于 TLB 未命中而导致的性能开销 我希望通过使用一些性能计数器来获得这个估计 有人知道估计这个的最佳方法是什么吗 谢谢 阿尔卡 如果您可以访问基于 West
  • 我可以限制 php 脚本的最大 CPU 使用率吗?

    我有一些使用大量 cpu 的脚本 是否可以限制允许进程使用的 cpu 量 顺便说一句 我正在 CentOs 5 5 上运行 我帮助一位 PHP 编码员创建了解决类似问题的 PHP 脚本 这些是长时间运行的 PHP 脚本 会产生大量负载 由于
  • 图片可以有多个标签吗?

    例如 当我将新图像推送到存储库时 我希望它有两个标签0 2 and latest 这将允许始终通过使用拉取最新的图像版本latest标签和特定版本使用0 2例如标签 用docker可以吗 有什么解决方法吗 我看到的唯一解决方案是进行两次单独
  • React.js 中的悬停按钮

    我想问如何制作一个按钮 但是当鼠标位于按钮上 悬停 时 新按钮显示在前一个按钮上方 并且它在react js中 thx 这是我的代码的方式 var Category React createClass displayName Categor
  • Apple 关联文件在开发中获取,但在 TestFlight 和 App Store 中未获取

    通用链接在开发中工作得很好 但是一旦我对应用程序进行签名并将其部署到 TestFlight 和 App Store 似乎未获取 apple app site association 因此该应用程序未注册以打开通用链接 1 well know
  • 如何在 Angular 6 中调用多个 API 并订阅?

    在我的应用程序中 调用所有POST请求我已经使用了service 当我得到一个specific code 例如 401 我从服务器调用 API 来获取新令牌 在收到另一个令牌之前 如果有任何其他 API 调用 我会将所有这些请求存储在一个数
  • 元素的 jQuery 标签名称

    我尝试在 jQuery 中获取元素标签名称 我有以下 html div class section h1 New Revision nbsp img alt Lock closed class edit src assets lock cl
  • 从网络提供商处获取准确的当前位置

    我使用以下代码从应用程序中的网络提供商获取当前位置 LocationManager mgr LocationManager getSystemService LOCATION SERVICE boolean network enabled
  • 在 vue 组件上提交表单时如何获取单选按钮的值?

    我有两个组件 我的第一个组件是这样的
  • Chronicle 与 Chronicle-queue 包

    我刚刚开始使用历史记录队列 但是我对使用哪个 API 来读取 写入队列有点困惑 具体来说编年史队列 5 https www javadoc io doc net openhft chronicle queue 5 17 17 vs 编年史
  • 如何解释 EL 表达式中方括号 ([]) 运算符的用法

    当我阅读时春天宠物诊所 https github com SpringSource spring petclinic 示例应用程序 我发现他们总是把add and modify功能集成到单个 JSP 文件中 并且它们使用 owner new
  • 在 C# 中将 LDAP AccountExpires 转换为 DateTime

    我想将 LDAP AccountExpires 中的 18 位数字字符串转换为正常日期时间格式 129508380000000000 gt gt 2011年5月26日 我通过使用以下链接获得了上述转换 http www chrisnowel
  • Admob 插页式广告显示为黑色,并带有新的广告单元 ID

    我创建了一个应用程序 并且正在使用 admob 插页式广告 由于我已为该应用程序创建了新的插页式广告单元 ID 但广告显示为黑色并带有关闭按钮 但如果我使用旧的应用程序 广告单元 ID 广告将会显示 我不知道为什么会出现这个问题 谢谢 对于
  • 泛型地狱:hamcrest 匹配器作为方法参数

    因此 让我们有一个字符串列表和一个函数 该函数采用 Hamcrest 匹配器并返回matches 提供的匹配器的方法 public boolean matchIt final Matcher
  • 如何在 Notepad++ 中多行“在文件中替换...”

    如果有免费的源代码编辑器记事本 http notepad plus sourceforge net uk about php具有 在文件中查找 功能 即无需在编辑器中打开文件 它是否也具有 在文件中替换 功能 Notepad 是基于Note
  • 如何从 PhantomJS 或 grover 跳过代码执行

    接下来的问题是 我的应用程序中有 JavaScript 代码 我想跳过 隐藏 PhantomJS 和 grover 检查 执行中的一些代码 So 如何跳过 隐藏 PhantomJS 或 grover 的代码执行 注意 当我编写 JavaSc
  • 无法定义使用动态的类或成员,因为编译器需要类型

    我在 Asp Net 3 5 应用程序中使用 Facebook SDK C 库 当我尝试编译下面的代码时 请给我错误 据我所知 动态类型在 4 0 框架中使用 那么无论如何要重写它才能使其工作吗 我有一个对 System Core 3 5
  • 单值上下文中的多个值

    由于 Go 中的错误处理 我经常会得到多个值函数 到目前为止 我管理此问题的方式非常混乱 我正在寻找最佳实践来编写更清晰的代码 假设我有以下功能 type Item struct Value int Name string func Get