sinomoe / sino.moe

just a simple issue blog
http://sino.moe
0 stars 1 forks source link

golang中的下划线 #3

Open sinomoe opened 6 years ago

sinomoe commented 6 years ago

最近,在阅读gin的代码的过程中看到了一些奇怪的下划线用法。

render/render.go中又如下一段:

type Render interface {
    Render(http.ResponseWriter) error
    WriteContentType(w http.ResponseWriter)
}

var (
    _ Render     = JSON{}
    _ Render     = IndentedJSON{}
)

能看到定义了一个Render的接口,然而让人不解的是下面两句,不禁猜测这里的下划线用途。值得一提的是这里的结构体JSONIndentedJSON均实现了Render接口,大致上能猜出来可能是为了验证是否实现了接口而申明的。

经过简单的搜索,发现这样的代码在gin中还有不少,遂一一验证,并逐步验证了猜想。

准确的说,这里的下划线是用来配合接口和类型做断言的,当赋值的类型所需未实现接口时,编译就会报错。在这里,JSONIndentedJSON是实现了Render接口的结构体类型,所以赋值不会引起编译错误。

golang中下划线的应用场景

1. 忽略赋值

func Foo() int, int, int {
    return 1, 2, 3
}
a, b, _ := Foo()

2. 接口断言

正如前文所述

3. import引入

在import中使用下划线将不会直接引入包,只会执行被引包中的init函数

package foo

import _ "bar"
package bar

func init() {}

正如上述代码所示,在foo包中使用下划线引入了bar包,将会执行bar里的init函数,而不是引入bar包。这一特性在实践中也十分常见。