乐趣区

关于golang:Go语言中fmtPrintlntrue的结果一定是true么

背景

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…
退出移动版