Go 返回可选值和错误

Go 返回可选值和错误,go,Go,对于返回可选值和可能错误的函数,最好的签名是什么 例如: func findColor(name string) (RGB, error) { ... } (空RGB值为黑色,这是一种有效颜色,因此您无法使用它来推断未找到任何值。假设错误可能来自数据库连接之类的原因。) 看起来最好的两个选项是布尔返回值: func findColor(name string) (RGB, bool, error) { ... } c, ok, err := findColor(myname)

对于返回可选值和可能错误的函数,最好的签名是什么

例如:

func findColor(name string) (RGB, error) {
    ...
}
(空RGB值为黑色,这是一种有效颜色,因此您无法使用它来推断未找到任何值。假设错误可能来自数据库连接之类的原因。)

看起来最好的两个选项是布尔返回值:

func findColor(name string) (RGB, bool, error) {
    ...
}

c, ok, err := findColor(myname)

if !ok {
    ...
} else if err != nil {
    ...
}

...
或一个特殊的错误值:

var ColorNotFound = errors.New(...)

func findColor(name string) (RGB, error) {
    ...
}

c, err := findColor(...)

if err == ColorNotFound {
    ...
} else if err != nil {
    ...
}

...
(犯特殊错误似乎很痛苦。)


最惯用的方法是什么?

围棋中的惯例是返回
(值,错误)
和if
错误!=nil
无效(或可能无效)

如果你有特殊的错误,你需要做一些事情(如),然后作出一个具体的错误是正常的做法。因此,如果您想为
ColorNotFound
做一些不同的事情,我想说您的第三个示例是最惯用的

var ColorNotFound = errors.New(...)

func findColor(name string) (RGB, error) {
    // ...
}

c, err := findColor(...)

if err == ColorNotFound {
    // Do something special if ColorNotFound...
} else if err != nil {
    // Some other kind of error...
}

您可以使
findColor
返回
*RGB
,然后将其与nil进行比较:

c, err := findColor(name)
if err != nil { /* Handle error. */ }
if c == nil { /* Handle no color. */ }
但这是不安全的,因为如果您试图调用
nil
指针上的方法,它们可能会引起恐慌


我建议您坚持使用一种特殊的
ErrColorNotFound
方法。

我不确定您是否想强调“can”部分。以防万一,你没有:@SimonWhitehead是的,我添加了“can”,因为当接收器为
nil
时,方法可能不会死机。如果您的
RGB
类型的所有方法都可以处理这种情况,并且没有假设
*RGB
在代码中的任何地方都是非零的,那么您就可以了。否则,请使用错误。