Go 语言基础语法

思维导图预习

go-基础语法-思维导图.png


命名

命名规则

Go 语言中的函数名、变量名、常量名、类型名、语句标号和包名等所有的命名,都遵循一个简单的命名规则:

一个标识符必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线。

关键字

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-源码解读-标识符

有大约 30 多个预定义的标识符,比如 int 和 true 等,主要对应内建的常量、类型和函数。

这些内部预先定义的名字并不是关键字,你可以在定义中重新使用它们。

内建常量: true false iota nil

内建类型: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error

内建函数: make len cap new append copy close delete
complex real imag
panic recover

标识符可见范围

如果一个名字是在函数内部定义,那么它就只在函数内部有效。如果是在函数外部定义,那么将在当前包的所有文件中都可以访问。

名字的开头字母的大小写决定了名字在包外的可见性。如果一个名字是大写字母开头的,那么它将是导出的,也就是说可以被外部的包访问。


声明

声明语句定义了程序的各种实体对象以及部分或全部的属性。

  • var:变量声明
  • const:常量声明
  • type:类型声明
  • func:函数实体对象声明

变量

var 声明语句

var 声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:

var 变量名字 类型 = 表达式

简短变量声明

在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量,变量的类型根据表达式来自动推导。

因为简洁和灵活的特点,简短变量声明被广泛用于大部分的局部变量的声明和初始化。var 形式的声明语句往往是用于需要显式指定变量类型的地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

i := 100                  // an int
var boiling float64 = 100 // a float64

变量的生命周期

变量的生命周期指的是在程序运行期间变量有效存在的时间段。

  • 对于在包一级声明的变量来说,它们的生命周期和整个程序的运行周期是一致的。
  • 局部变量的生命周期则是动态的:每次从创建一个新变量的声明语句开始,直到该变量不再被引用为止,然后变量的存储空间可能被回收。

函数的参数变量和返回值变量都是局部变量。它们在函数每次被调用的时候创建。


赋值

使用赋值语句可以更新一个变量的值,最简单的赋值语句是将要被赋值的变量放在 = 的左边,新值的表达式放在 = 的右边。

x = 1                       // 命名变量的赋值
*p = true                   // 通过指针间接赋值
person.name = "bob"         // 结构体字段赋值
count[x] = count[x] * scale // 数组、slice或map的元素赋值

空白标识符

和变量声明一样,我们可以用下划线空白标识符 _ 来丢弃不需要的值。

_, err = io.Copy(dst, src) // 丢弃字节数
_, ok = x.(T)              // 只检测类型,忽略具体值

类型

一个类型声明语句创建了一个新的类型名称,和现有类型具有相同的底层结构。新命名的类型提供了一个方法,用来分隔不同概念的类型,这样即使它们底层类型相同也是不兼容的。

type 类型名字 底层类型

类型声明语句一般出现在包一级,因此如果新创建的类型名字的首字符大写,则在包外部也可以使用。


包和文件

Go 语言中的包和其他语言的库或模块的概念类似,目的都是为了支持模块化、封装、单独编译和代码重用。

包的初始化

对于在包级别声明的变量,如果有初始化表达式则用表达式初始化,还有一些没有初始化表达式的,可以用一个特殊的 init 初始化函数来简化初始化工作。

func init() { /* ... */ }

这样的 init 初始化函数除了不能被调用或引用外,其他行为和普通函数类似。在每个文件中的 init 初始化函数,在程序开始执行时按照它们声明的顺序被自动调用。

每个包在解决依赖的前提下,以导入声明的顺序初始化,每个包只会被初始化一次。因此,如果一个 p 包导入了 q 包,那么在 p 包初始化的时候可以认为 q 包必然已经初始化过了。初始化工作是自下而上进行的,main 包最后被初始化。以这种方式,可以确保在 main 函数执行之前,所有依赖的包都已经完成初始化工作了。


作用域

一个声明语句将程序中的实体和一个名字关联,比如一个函数或一个变量。声明语句的作用域是指源代码中可以有效使用这个名字的范围。

作用域和生命周期区别

  • 声明语句的作用域对应的是一个源代码的文本区域,它是一个编译时的属性。
  • 一个变量的生命周期是指程序运行时变量存在的有效时间段,在此时间区域内它可以被程序的其他部分引用,是一个运行时的概念。

思维导图复习

go-基础语法-思维导图.png

Next