如何在golang中返回int或nil?

21

我是一名Java开发者,正在学习Go语言。 我正在为一个LIFO栈写简单的“pop”操作。问题是当栈中没有值时如何返回值。在Java中,我可以在正常情况下返回一个包装器(Integer),当没有值时返回null。这个方式对我来说很自然。

在Go中我该怎么做呢?是否有基本类型的结构体包装器?我需要返回两个值(第二个将指示错误代码)吗?还是应该抛出异常?

目前这是它的样子:

func (s *stack) Pop() (int, bool)  {
    if s.size == 0 {
        return 0, true
    }
    s.size--
    val := s.stack[s.size]
    return val, false
}

这是好的风格吗?


你可以返回一个 *int。不过我不确定这是否合适。 - Ry-
请注意,该编程语言被称为“Go”,两个字母,第一个大写。 "golang"是域名的一部分,也是一种特殊的关键词,被一家公司拥有的流行搜索引擎所理解,该公司是Go开发的起源地。 - kostix
另一个要点是Go没有异常(幸运的是)。它有panic()recover(),但它们不是异常将错误视为值,并考虑优雅地处理它们;-) - kostix
2个回答

34

由于数字不能为nil,因此您无法返回nil作为整数,除非将返回值定义为指针。Go语言中的惯用解决方案是定义方法返回多个值,例如:

由于数字不能为nil,因此您无法返回nil作为整数,除非将返回值定义为指针。Go语言中的惯用解决方案是定义方法返回多个值,例如:

func (s *stack) Pop() (int, bool) {
    //does not exists
    if ... {
        return 0, false
    }

    //...

    //v is the integer value
    return v, true
}

然后在某个地方,您可以调用Pop,如下所示:

s := &stack{}
if v, ok := s.Pop(); ok {
    //the value exists
}

看一下逗号OK惯用语


谢谢。这是我现在的代码,请纠正如果有不符合'go'风格的地方:func (s *stack) Pop() (int, bool) { if s.size == 0 { return 0, true } s.size-- val := s.stack[s.size] return val, false } - the_kaba
3
第一个返回值应为:return 0, false,第二个返回值应为:return val, true - putu

3

Go语言中没有try/catch结构,因此您不能依赖它。

相反,Go语言有一个很好的特性,允许返回多个值。而他们的错误处理就是基于此构建的。

因此,处理可能出现异常的规范方式是同时返回一个值和一个错误。在操作完成后,检查并处理错误,并忽略该值。在您的情况下,可以将该值保留为int类型,并在出现错误时使用默认值0。由于客户端在这种情况下希望忽略该值并对错误进行处理。


但是如果堆栈可以包含0怎么办?对我来说,从客户端的角度来看,这似乎很丑陋。例如,我们知道0可以表示错误,并且我们有第二个布尔值,当我们有异常时为true: if resp0 == 0 && resp1 == true { // 异常处理 }您的意思是这样写吗? - the_kaba
3
你应该_始终_检查错误条件。所以如果你没有收到错误,但是弹出的值为0,那么你知道这是一个好的值。测试应该简单地为if resp1 != nil { // exception handling }。在你知道resp1 == nil且没有发生错误之前,不要查看resp0。因此,你可以相信resp0是来自堆栈的有效值。Go就是这样教条主义。你不应该忽略错误,而应该尽快处理它,而不是在稍后的catch语句块中处理它。 - Horia Coman
2
通常对于这样一个简单的情况,使用布尔值而不是错误,但对于一般情况来说这是正确的。在两种情况下,在执行任何其他操作之前,您应始终检查错误/布尔值。在这里发布了许多问题,如果提问者正确检查错误,答案将会很明显。 - Milo Christiansen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接