Open sinomoe opened 6 years ago
最近,在阅读gin的代码的过程中看到了一些奇怪的下划线用法。
在render/render.go中又如下一段:
render/render.go
type Render interface { Render(http.ResponseWriter) error WriteContentType(w http.ResponseWriter) } var ( _ Render = JSON{} _ Render = IndentedJSON{} )
能看到定义了一个Render的接口,然而让人不解的是下面两句,不禁猜测这里的下划线用途。值得一提的是这里的结构体JSON和IndentedJSON均实现了Render接口,大致上能猜出来可能是为了验证是否实现了接口而申明的。
Render
JSON
IndentedJSON
经过简单的搜索,发现这样的代码在gin中还有不少,遂一一验证,并逐步验证了猜想。
准确的说,这里的下划线是用来配合接口和类型做断言的,当赋值的类型所需未实现接口时,编译就会报错。在这里,JSON和IndentedJSON是实现了Render接口的结构体类型,所以赋值不会引起编译错误。
func Foo() int, int, int { return 1, 2, 3 } a, b, _ := Foo()
正如前文所述
在import中使用下划线将不会直接引入包,只会执行被引包中的init函数
init
package foo import _ "bar"
package bar func init() {}
正如上述代码所示,在foo包中使用下划线引入了bar包,将会执行bar里的init函数,而不是引入bar包。这一特性在实践中也十分常见。
foo
bar
最近,在阅读gin的代码的过程中看到了一些奇怪的下划线用法。
在
render/render.go
中又如下一段:能看到定义了一个
Render
的接口,然而让人不解的是下面两句,不禁猜测这里的下划线用途。值得一提的是这里的结构体JSON
和IndentedJSON
均实现了Render接口,大致上能猜出来可能是为了验证是否实现了接口而申明的。经过简单的搜索,发现这样的代码在gin中还有不少,遂一一验证,并逐步验证了猜想。
准确的说,这里的下划线是用来配合接口和类型做断言的,当赋值的类型所需未实现接口时,编译就会报错。在这里,
JSON
和IndentedJSON
是实现了Render
接口的结构体类型,所以赋值不会引起编译错误。golang中下划线的应用场景
1. 忽略赋值
2. 接口断言
正如前文所述
3. import引入
在import中使用下划线将不会直接引入包,只会执行被引包中的
init
函数正如上述代码所示,在
foo
包中使用下划线引入了bar
包,将会执行bar里的init函数,而不是引入bar包。这一特性在实践中也十分常见。