背景

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...