当前位置: 首页 > 面试题库 >

单值上下文中的多个值

刘京
2023-03-14
问题内容

由于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,它的存在是有 原因 (这是函数 可能会 失败),你应该 不会 绕过它,因为如果你这样做,你后面的代码 可能
也惨遭失败(如导致运行时的恐慌)。

但是,在某些情况下,您 知道 代码在任何情况下都不会失败。在这些情况下,您可以提供一个 辅助 函数(或方法),该函数将放弃 辅助
函数(或方法,error如果仍然发生,则会引起运行时恐慌)。
如果您从代码中提供了函数的输入值,并且知道它们可以工作,则可能是这种情况。和软件包
就是一个很好的例子:如果在编译时提供了有效的模板或regexp,则可以确保在运行时始终可以对它们进行分析而不会出错。因此,包提供了功能,包提供了功能:它们不返回templateregexptemplateMust(t *Template, err error) *TemplateregexpMustCompile(str string) *Regexperror,因为它们的预期用途是保证输入有效的地方。

例子:

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

回到你的情况

如果
可以确定Get()不会error为某些输入值生成,则可以创建一个辅助Must()函数,该函数将不返回,error但如果仍然发生则引发运行时恐慌:

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

但是,您不能在所有情况下都使用它,除非您确定它会成功。用法:

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

替代/简化

如果将Get()调用合并到辅助函数中,您甚至可以进一步简化它,让我们称之为MustGet

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

用法:

val := MustGet(1).Value

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

如何解析golang中的多个收益

使用正常功能在Golang中返回类似“
ok”的地图



 类似资料:
  • 问题内容: 我有以下代码: 我收到了错误: 根据我在Internet上找到的所有内容,这意味着我忽略了ParseInt返回的两个参数,但我使用的是err。我知道错误可能很愚蠢,但是我刚开始学习Go,这让我很困惑。 问题答案: 表达式是类型转换,它不能有多个参数(操作数),但是由于有2个返回值,因此基本上都是将两者都传递给类型转换,这是无效的。 而是这样做: 请注意,基数不能大于,因此在传递基数时肯

  • 问题内容: 有人可以解释为什么这行代码: 正在产生这些错误: 谢谢!布赖恩 问题答案: 两者都返回错误,因此您不能直接分配它们。 您至少需要忽略错误返回值。 带有: 但是最佳做法是检查错误,如果不是,请采取措施。 实际上,twotwotwo在注释中添加了: 不过,请不要忽略,否则有一天您的程序将无法执行应做的事情,并且您将不知道为什么。 很多时候,您希望函数也返回错误,而您想要的“默认”处理程序是

  • 问题内容: 我有一个这样的STRING切片数组: 请记住,阵列不断增加。我只是发布一个示例数组。 现在,我将一些浮点数转换为字符串,以便可以将其附加到字符串切片中。但是,我需要对这些数字进行一些数学运算。我想将第二个切片的字符串编号(5343340.56343)添加到第三个字符串编号(22139.461201388)。每片中的其他2个浮点数都相同。为此,我需要先将它们转换为float64。得到总和

  • 我有一个带有主窗口的应用程序。它有自己的线程和opengl上下文。这个应用程序每个处理器还有一个工作线程来创建和上传软件渲染的纹理。这工作得非常好。 我担心的是工作线程opengl上下文是使用主窗口的device_context创建的。因此,在双处理器系统的情况下,这意味着3个opengl上下文被绑定到同一个window device_context。它们都是在主窗口线程中创建的,然后调用shar

  • 问题内容: 我正在使用通过上下文传递的函数。 现在我用。这可行。 如果我需要来自两个不同父组件的函数,该怎么办? 问题答案: 您仍然可以通过16.3 Context API来使用子级功能消费者节点,这是React文档建议的做法: 要在组件的上下文中使用函数,通常将组件包装在HOC中,以便将上下文作为prop传递: 如果您正在运行React 16.8+,则还可以使用钩子更干净地执行此操作,而无需使用

  • 我使用部署在ActiveMQ服务内部的Apache Camel模块。 假设我使用Spring DSL并且在文件(简化版)中有路由定义(实现为): 接下来,我在其他XML文件(简化)中配置了骆驼上下文: 我希望使用IoC术语将来自的共享路由(ID=)声明为每个依赖项的实例,因此来自单个骆驼上下文(ID=、、)的每条路由都应该使用该共享路由的自己的实例(ID=),具有单独的内部状态和bean实例等。