背景
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.gopackage mainimport "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 selectcase defer go map structchan else goto package switchconst fallthrough if range typecontinue 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 uintptrConstants: true false iotaZero value: nilFunctions: append cap close complex copy delete imag len make new panic print println real recover
因而true := false
这样的代码在Go语言是能够失常编译通过的,并且go vet
也不会检测出任何潜在谬误。
不仅仅是true
,预申明标识符里的所有标识符都能够用来作为全局变量和局部变量的标识符,比方上面的代码:
// identifier2.gopackage mainimport "fmt"var nil = 100var false = truefunc 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...