go语言的初始化顺序,包,变量,init详解

Go语言的初始化顺序,包,变量,init详解

在Go语言中,程序的初始化是从包的引入开始的。初始化的顺序非常重要。

包的初始化顺序

在包被import引入到程序中时,Go将按照以下顺序初始化包:

1.首先,Go将计算所有包级别的变量的值并执行所有init函数。这假定这些变量和init函数没有依赖于任何其他包。它们只依赖于标准库和编译器定义的本地实体。

2.接着,Go将按照以下顺序对每个非main包执行其依赖关系图上的init函数。
对一个包的初始化仅在第一次加载时运行。可以通过导入路径来引用这个包,也可以通过空白标识符(_)来强制编译器加载这个包。即使是没有用到的包,编译器也会加载它们,并触发它们的init函数。

注意:如果循环导入了两个或多个包,Go编译器将会报错。

示例1:包的初始化顺序

假设有以下三个包:pkgA,pkgB,pkgC。它们依赖关系如下:

main -> pkgA -> pkgB -> pkgC

现在,让我们假设main包导入pkgA包,pkgA包导入pkgB包,pkgB包导入pkgC并且三个包中均有一个init函数。在这个情况下,初始化顺序如下:

1.pkgC被导入,并且pkgC的init函数被执行。
2.pkgB被导入,并且pkgB的init函数被执行。
3.pkgA被导入,并且pkgA的init函数被执行。

需要注意的是,即使只导入了pkgA包,系统会自动将pkgB和pkgC包加载到内存,并执行它们的init函数。这是因为pkgA依赖pkgB,而pkgB依赖pkgC。

变量的初始化顺序

在每个包中,变量的初始化值是通过声明它们时提供的表达式来确定的。在一个大的编译单元中,包的变量将采用以下顺序进行初始化:

1.包级别变量,不依赖其他包里面的元素。
2.按包的依赖性顺序初始化每个包级别变量。

示例2:变量的初始化顺序

package main

import "fmt"

var a = "hello"

func init() {
    fmt.Println("init1")
}

func init() {
    fmt.Println("init2")
}

func main() {
    fmt.Println(a)
}

上面的代码中,变量a被初始化为字符串"hello"。在这个示例中,init1init2a被初始化之前执行。

init函数的使用

每个包可以包含任意数量的init函数。这些函数是在程序运行开始时按顺序执行的。
init函数不能接受任何参数或返回值。也就是说,它们在运行时无法与其他函数进行通信。

示例3:init函数的使用

package main

import "fmt"

func init() {
    fmt.Println("init1")
}

func init() {
    fmt.Println("init2")
}

func main() {
    fmt.Println("main")
}

上面的代码中,程序运行时将输出以下内容:

init1
init2
main

需要注意的是,init函数可以用来执行任何有关包的操作。这可能包括一些包的初始化逻辑、变量初始化或HTTP路由注册等等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:go语言的初始化顺序,包,变量,init详解 - Python技术站

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关文章

  • js 多种变量定义(对象直接量,数组直接量和函数直接量)

    JS 多种变量定义 在 JavaScript 中,有多种方式可以定义变量,包括对象直接量、数组直接量和函数直接量。下面将详细介绍每种方式的定义和示例。 对象直接量 对象直接量是一种创建对象的方式,使用花括号 {} 来定义对象,并在花括号内部使用键值对的形式来表示对象的属性和属性值。 // 定义一个对象直接量 const person = { name: ‘J…

    other 2023年8月15日
    00
  • springcloud gateway自定义断言规则详解,以后缀结尾进行路由

    Spring Cloud Gateway自定义断言规则详解 Spring Cloud Gateway是一个基于Spring Framework 5,Spring Boot 2和Project Reactor的API网关,它提供了一种简单而有效的方式来路由请求,并对请求进行过滤和修改。其中,自定义断言规则是一种强大的功能,可以根据请求的特定条件进行路由。 自定…

    other 2023年8月5日
    00
  • vue组件之时间组件

    vue组件之时间组件 在开发基于Vue框架的应用程序时,我们常常需要使用各种各样的组件来构建用户界面。其中,时间组件通常是我们不可或缺的组件。时间组件可以用于显示当前的日期和时间等信息。在这篇文章中,我们将介绍如何使用Vue框架来开发一个简单的时间组件。 设计时间组件 在开始编写时间组件之前,首先我们需要明确组件的设计需求。时间组件应当能够自动更新当前的时间…

    其他 2023年3月29日
    00
  • javascript递归函数定义和用法示例分析

    Javascript递归函数定义和用法示例分析 定义 递归函数指在函数内部调用函数本身的方式。在Javascript中,可以通过函数定义来实现递归函数的效果。 以下是递归函数的一般形式: function recursiveFunction(parameters) { // 基本案例 if () { return ; } // 递归调用 else { rec…

    other 2023年6月27日
    00
  • 浅谈CSS3 动画卡顿解决方案

    下面我就为你详细讲解“浅谈CSS3 动画卡顿解决方案”的完整攻略。 根本原因 首先,我们需要了解CSS3动画卡顿的根本原因。CSS3动画的实现方式是通过改变元素的样式来实现动画的效果,而当我们连续对一个元素进行多次样式改变时,就会发生卡顿的现象。 那么如何解决这个问题呢? 解决方案 1. 使用transform 可以使用transform代替position…

    other 2023年6月26日
    00
  • 深入了解C语言中常见的文件操作方法

    我们来深入了解C语言中常见的文件操作方法。 文件的基本操作 在C语言中,文件的操作可以分为三个步骤:打开文件、读写文件和关闭文件。文件的读写操作需要打开文件,并在操作完成后关闭文件。 打开文件 C语言的标准库提供了fopen()函数来打开文件,其函数原型如下: FILE *fopen(const char *filename, const char *mod…

    other 2023年6月26日
    00
  • CentOS 5.5 最新版下载地址 比较流行的服务器操作系统

    CentOS 5.5 最新版下载地址 比较流行的服务器操作系统攻略 CentOS是一种基于Red Hat Enterprise Linux(RHEL)源代码的自由开源操作系统,被广泛用作服务器操作系统。本攻略将详细介绍如何下载最新版的CentOS 5.5,并提供两个示例说明。 步骤一:访问CentOS官方网站 首先,访问CentOS官方网站以获取最新版的Ce…

    other 2023年8月4日
    00
  • 常用批处理内部命令使用详解

    常用批处理内部命令使用详解 简介 批处理是可以用来批量执行指令的脚本语言,常用于Windows系统中。批处理有许多内部命令可以使用,此文档将详细讲解批处理中常用的内部命令及其用法。 命令说明 ECHO ECHO命令可以输出文字、变量或命令的执行结果到屏幕上。 语法: ECHO [ON | OFF] [message] 示例: 输出“Hello World!”…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部