在普通函数中返回类似于Golang中的'ok'的映射

36
在Go语言中,以下代码是有效的(请注意,一个使用map的返回值为一个,另一个使用两个)
package main

import "fmt"

var someMap = map[string]string { "some key": "hello" }

func main() {
    if value, ok := someMap["some key"]; ok {
        fmt.Println(value)
    }

    value := someMap["some key"]
    fmt.Println(value)
}

然而,我不知道如何对自己的函数执行相同操作。是否有可能像map一样使用可选返回值实现类似的行为?

例如:

package main

import "fmt"

func Hello() (string, bool) {
    return "hello", true
}

func main() {
    if value, ok := Hello(); ok {
        fmt.Println(value)
    }

    value := Hello()
    fmt.Println(value)
}

因为错误 multiple-value Hello() in single-value context,代码无法编译... 有没有办法让这个语法适用于函数 Hello()

2个回答

47
map是一种内置的类型,而不是函数。访问map元素的两种形式由Go语言规范:索引表达式指定,并由编译器支持。
对于函数来说,你不能这样做。如果一个函数有两个返回值,你必须“期望”它们中的所有或者全部都没有。
但是,你可以将任何一个返回值赋值给空白标识符
s, b := Hello()    // Storing both of the return values

s2, _ := Hello()   // Storing only the first

_, b3 := Hello()   // Storing only the second

您也可以选择不存储任何返回值:
Hello()            // Just executing it, but storing none of the return values

注意:你也可以将这两个返回值都分配给空标识符,虽然它没有用处(除了验证它确实有两个返回值):
_, _ = Hello()     // Storing none of the return values; note the = instead of :=

你可以在Go Playground上尝试这些内容。 辅助函数 如果你需要多次使用它,而且不想使用空标识符,请创建一个辅助函数来忽略第二个返回值:
func Hello2() string {
    s, _ := Hello()
    return s
}

现在你可以做:

value := Hello2()
fmt.Println(value)

Go 1.18 泛型更新: Go 1.18 增加了泛型支持,现在可以编写一个通用的 First() 函数来丢弃第二个(或任何其他)返回值:

func First[T any](first T, _ ...any) T {
    return first
}

这些内容可以在github.com/icza/gog中找到,使用gog.First()方法(声明:我是作者)。

使用方法:

value := First(Hello())
fmt.Println(value)

5
我早就有这样的怀疑,但因在谷歌搜索文档或找到确切答案时遇到困难,所以不太确定。感谢提供文档的参考! - Michael Wasser

2
除了@icza的解释之外:
  • 我不建议在那里使用帮助函数。特别是如果Hello函数是您自己的函数。
  • 但是,如果您无法控制它,则使用辅助程序是可以的。
  • 如果它是您自己的函数,则最好更改函数的签名。可能,在某个地方您犯了设计错误。

您也可以这样做:

Original Answer翻译成"最初的回答"
package main

import "fmt"

func Hello() (string, bool) {
    return "hello", true
}

func main() {
    // Just move it one line above: don't use a short-if
    value, ok := Hello()
    if ok {
        fmt.Println(value)
    }
}

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