Go语言基础:Go入口函数

427 阅读4分钟

Go第二课-Go入口和目录

Go源文件

  1. Go 源文件总是用全小写字母形式的短小单词命名,并且以.go 扩展名结尾。
  2. 直接是将多个单词连接起来作为源文件名,而不是使用其他分隔符,比如下划线。
  3. 我们尽量不要用两个以上的单词组合作为文件名,否则就很难分辨了。

Go入口函数-main

  1. Go 语言中有一个特殊的函数:main 包中的 main 函数,也就是 main.main,它是所有 Go 可执行程序的用户层执行逻辑的入口函数。

  2. 包是 Go 语言的基本组成单元,通常使用单个的小写单词命名。

  3. 整个 Go 程序中仅允许存在一个名为 main 的包,入口 package 必须为 package main。可执行程序的 main 包必须定义 main 函数,入口函数必须为 func main(){},否则 Go 编译器会报错返回 runtime.main_main·f: function main is undeclared in the main package

  4. 在启动了多个 Goroutine(Go 语言的轻量级用户线程,后面我们会详细讲解)的 Go 应用中,main.main 函数将在 Go 应用的主 Goroutine 中执行。

  5. 但按照 Go 的可见性规则(小写字母开头的标识符为非导出标识符),非 main 包中自定义的 main 函数仅限于包内使用。

  6. 通常导入路径的最后一个分段名与包名是相同的。

  7. 只有首字母为大写的标识符才是导出的(Exported),才能对包外的代码可见;如果首字母是小写的,那么就说明这个标识符仅限于在声明它的包内可见。

  8. Go 源码文件本身采用的是 Unicode 字符集,而且用的是 UTF-8 标准的字符编码方式。

  9. Go 中 main函数 不支持返回值,使用os.exit() 作为返回值,否则会返回too many return values have (number) want ()

    package main
    
    import (
    	"fmt"
    	"os"
    )
    
    func main() {
    	fmt.Println("Hello World!")	
    	os.Exit(10)
    }
    
  10. Go中的 main 函数 不支持传参,使用 os.Args 作为传参

    func main() {
    	fmt.Println(os.Args[1])
    	fmt.Println("Hello World!")	
    	os.Exit(0)
    }
    

Go入口函数-init

  1. init 函数是一个无参数无返回值的函数。

  2. “main 函数不一定是用户层第一个被执行的函数”是因为如果 main 包依赖的包中定义了 init 函数,或者是 main 包自身定义了 init 函数,那么 Go 程序在这个包初始化的时候,就会自动调用它的 init 函数,因此这些 init 函数的执行就都会发生在 main 函数之前。

  3. 不能手工显式地调用 init,否则就会收到编译错误。

  4. 在初始化 Go 包时,Go 会按照一定的次序,逐一、顺序地调用这个包的 init 函数。一般来说,先传递给 Go 编译器的源文件中的 init 函数,会先被执行;而同一个源文件中的多个 init 函数,会按声明顺序依次执行。

  5. Go 在进行包初始化的过程中,会采用“深度优先”的原则,递归初始化各个包的依赖包。

    image.png

  6. 包中按照“常量 -> 变量 -> init 函数”的顺序先对包进行初始化。

  7. 包内的多个 init 函数按出现次序进行自动调用。

  8. 一个被多个包依赖的包仅会初始化一次。

  9. init 函数作用:

    1. 重置包级变量值。
    2. 是实现对包级变量的复杂初始化。
    3. 在 init 函数中实现“注册模式”。

Go 目录

  1. 对于以生产可执行程序为目的的 Go 项目,它的典型项目结构分为五部分:

    1. 放在项目顶层的 Go Module 相关文件,包括 go.mod 和 go.sum;
    2. cmd 目录:存放项目要编译构建的可执行文件所对应的 main 包的源码文件;
    3. 项目包目录:每个项目下的非 main 包都“平铺”在项目的根目录下,每个目录对应一个 Go 包;
    4. internal 目录:存放仅项目内部引用的 Go 包,这些包无法被项目之外引用;
    5. vendor 目录:这是一个可选目录,为了兼容 Go 1.5 引入的 vendor 构建模式而存在的。这个目录下的内容均由 Go 命令自动维护,不需要开发者手工干预。
  2. 对于以生产可复用库为目的的 Go 项目,它的典型结构则要简单许多,可以直接理解为在 Go 可执行程序项目的基础上去掉 cmd 目录和 vendor 目录。