背景
Honeycomb 的首席开发布道者 Jessica 在 Twitter 上发了一条状态:
fmt.Println(“What is truth?”, true)
can output:
What is truth? false
意思是上面代码的执行后果可能是What is truth? false
fmt.Println("What is truth?", true)
大家能够先想想什么状况下会呈现这样的后果。
解析
咱们来看上面这段代码:
// identifier.go
package main
import "fmt"
func main() {
true := false
fmt.Println(true)
}
大家感觉这段代码是会编译报错呢,还是失常执行?
理论执行后果是打印false
,并不会编译报错。
因而本文结尾的代码 fmt.Println("What is truth?", true)
是可能打印 What is truth? false
的。
有的同学可能好奇了?为什么会这样呢?true
不是 Go 语言的关键字么,为什么还能够定义标识符为true
的变量?
答案是:true
并不是 Go 语言的关键字,Go 语言目前只有 25 个关键字,如下所示:
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
这些关键字是不能够用来作为 Go 语言的标识符的。true
是预申明标识符,是能够作为 Go 语言的标识符的,官网阐明如下:
Predeclared identifiers
The following identifiers are implicitly declared in the universe block:
Types: bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr Constants: true false iota Zero value: nil Functions: append cap close complex copy delete imag len make new panic print println real recover
因而 true := false
这样的代码在 Go 语言是能够失常编译通过的,并且 go vet
也不会检测出任何潜在谬误。
不仅仅是true
,预申明标识符里的所有标识符都能够用来作为全局变量和局部变量的标识符,比方上面的代码:
// identifier2.go
package main
import "fmt"
var nil = 100
var false = true
func main() {
true := false
fmt.Println(true, false, nil)
}
大家能够想想输入后果是什么?
- A:
true false nil
- B:
true false 100
- C:
true true 100
- D:
false true 100
- E:
false true nil
想晓得答案的能够给公众号发送音讯 bsf
获取答案。
总结
Go 语言的这个个性也引起了很多争议,正如 Go 的错误处理一样。
咱们作为使用者,须要留神:Go 不容许把关键字作为标识符,其它都能够作为标识符。
开源地址
文章和示例代码开源在 GitHub: Go 语言高级、中级和高级教程。
公众号:coding 进阶。关注公众号能够获取最新 Go 面试题和技术栈。
集体网站:Jincheng’s Blog。
知乎:无忌。
References
- https://twitter.com/jessitron…
- https://go.dev/ref/spec#Keywords
- https://go.dev/ref/spec#Prede…