Go-程序结构 | 青训营笔记

79 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第1天

程序结构

命名

1.命名规则

必须以字母或下划线开头,后面可以跟任意字母,数字和下划线,区分大小写

2.作用域

在函数内部定义则只能在函数内部使用,在函数外部即包级名字在属于当前包的所有源文件中都可使用,如果想要在包外部访问,则可将名字改为大写

声明

Go中主要有四种类型的声明语句

  • var 定义变量
  • const 定义常量
  • type
  • func 定义函数;由函数名字、参数列表、可选的返回值列表、函数体

函数内部的变量需要先声明才能使用,而包一级的不论先后顺序

变量

1.变量的声明方式

  • var 变量名 变量类型 = 表达式

    • 变量类型可省略,将根据表达式智能判断
    • 初始化表达式也可以不写,变量将会被赋值为对应类型的零值;
    • 二者只可省其一
  • var a,b,c 变量类型;

    • 三个变量的类型都将以最后的变量类型为准
  • var a, b, c = true, 2.3, "hh"

    • 将会根据初始化表达式只能判断其类型
  • var a, b = os.Open(name)

    • 一组或单个变量也可通过函数的返回值来初始化

包级别的变量在main函数执行前初始化完成,局部变量将在声明语句被执行时声明

2.简短变量声明

  • 简短变量声明只需在变量的后面加 := 即可完成变量的声明和初始化

  • 若变量已经在同级词法域声明过,那么该行为将等同于赋值操作;若变量在外部词法域被声明过,将会声明一个新变量并对其进行赋值。但一组变量中至少要有一个未声明的变量,否则将会报错

3.指针

一个指针对应一个变量的内存地址,我们可以通过指针来访问或更新一个变量的值。若变量是由表达式临时创建的,那么表达式也能接受取地址的操作,比如在函数中返回局部变量地址的行为是被允许的,该变量在函数执行完之后依然有效

4.new函数

可以用new(T)来创建匿名的变量,返回一个内存地址,返回的指针类型为*T;new只是一个预定义的函数,我们可以将new名字重新定义为新的类型,但在该词法域中,将无法使用new函数

5.变量的生命周期

包一级声明的变量与整个程序的运行周期一致,而局部变量的生命周期则是动态的:直到其不再被引用为止

当一个短生命周期的变量被长生命周期的变量引用时会导致该变量无法被垃圾回收从而导致影响程序的性能

赋值

  • 通过 = 赋值,也可与二元算术运算符复合操作

  • 自增自减是语句而不是表达式,++或--只可放在变量的后面

元组赋值

允许同时更新多个变量的值,在赋值之前,赋值语句右边的表达式将先求值再更新左边变量的值。因此相比在C语言中交换两个变量的值需要借助一个中间变量,Go直接交换即可

类型

类型声明

type 类型名 底层类型

用来分割不同的概念类型,即使底层类型是相同的也是不兼容的,即他们不能被相互比较或混在一个表达式运算

类型转换

  • 任意一个类型T都对应一个对应的类型转换操作符T(x),可以将x转换成T类型

  • 这仅限于底层数据类型相同时才能转换

比较

比较可以发生在相同类型间,也可以发生在类型及与其有相同底层类型的未命名类型的值之间

类型的方法集

命名类型可以为该类型的值定义一组关联到改类型的函数集合

包和文件

  • 包对应其他语言的库或模块,目的是为了支持模块化、封装和代码重用。通常一个包的源代码在一个或多个以.go为后缀的源文件中

  • 每个包都对应一个名字空间,即不同的包中即便名字相同也代表不同的含义,因此在调用包中的函数或变量时应加上包的名字

  • 包级别的名字,在同一个包不同源文件中也是可以直接访问的,这仿佛是在同一个源文件中

  • 通常源文件包声明前要用注释解释包有什么功能,一个包中一个源文件有注释即可

  • 如果导入包但没有使用该包会报错

包的初始化

包的初始化首先解决包级变量的依赖顺序,然后按照包级变量声明出现的顺序依次初始化,这也就是包级变量在调用时不需要考虑变量声明顺序

程序的初始化

  • 程序的初始化先初始化导入的包,先解析包的依赖关系,先初始化没有依赖的包,然后根据包的依赖关系进行初始化,每个包仅初始化一次
  • 初始化包作用域的变量
  • 执行init函数
  • 执行main函数

init函数

作用

对不能采用初始化表达式初始化的变量进行初始化

主要特点
  • 先于main函数执行,不能被其他函数调用
  • 没有输入参数和返回值
  • 每个包可以由多个init函数,每个源文件也可以有多个init函数

作用域

作用域与声明周期

作用域对应的是一个源代码的文本区域;是编译时的属性

生命周期是指程序运行时变量存在的有效时间段,在此时间段内可以被程序的其他部分引用,是运行时的概念

句法块与词法块

句法块是被花括号所包含的一系列语句

词法块是未显式用花括号裹起来的声明语句