使用'逗号确定'成语或返回指针?

har*_*arm 6 idioms go

考虑以下Go片段:

func sheep() (int, bool) {
    return 1, true
}

func main() {
    if dolly, ok := sheep() {
         //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

当我读到'Effective Go'时,这被称为'逗号确定'成语.据我所知,这用于区分"发现"和"未找到"的东西.

同样可以通过以下方式实现:

type Sheep struct {}

func sheep() *Sheep {
    return &Sheep{}
}

func main() {
    if dolly := sheep(); dolly != nil {
         //do something
    }
}
Run Code Online (Sandbox Code Playgroud)

后一个例子似乎实现了同样的目的,甚至可能更好.使用'逗号ok'示例,赋值仅在if块中有效.

也许我错过了一些考虑因素.哪种模式更受欢迎?为什么?

一个简短的例子:http://play.golang.org/p/ATxvle38iE

Jim*_*imB 7

两者都是可以接受的,而且你错过了最常见的习语; 回来value, error.

"Effective Go"中引用的"逗号ok"惯用法通常保留给内置操作,例如从地图或通道读取,以及类型断言.

如果你需要返回一个指针不必要,不方便或者nil是有效值的值,我会使用它; 但视情况value, error而定可能同样好.

  • 为什么除了“逗号错误”之外,他们还引入“逗号好”?这看起来像是错失了保持一致性的机会,所以我想这是有充分理由的。 (2认同)

Pau*_*kin 7

在Go中,nil值可能是非常好的值.例如,nil切片(几乎)像空切片一样工作,对于用户定义的指针接收器也是如此.

出于这个原因,通常首选逗号或逗号错误习惯用法,因为它显然函数的调用者需要明确地处理错误情况(或不正常)情况.

因此,当Sheep返回值可能无效时,这些都是惯用的:

func sheep() (*Sheep, bool) {...}
func sheep() (s *Sheep, ok bool) {...}  // Adding names to make it clearer
func sheep() (*Sheep, error) {...}
Run Code Online (Sandbox Code Playgroud)

只有当返回值始终有效时,这才是惯用语:

func sheep() *Sheep {...}
Run Code Online (Sandbox Code Playgroud)

这是Go与其他语言不同的区域,其中可以使用nil返回值来表示错误.逗号和逗号错误的Go成语通过使不处理无效返回值的代码看起来错误,巧妙地解决了nil指针的"十亿美元错误".如果您编写惯用代码,您可以立即看到错误被忽略的时间:例如,s2此处的分配会立即跳出为可疑:

s1 := sheep()
s2, _ := sheep()
Run Code Online (Sandbox Code Playgroud)