当前位置: 首页 > news >正文

【Go 基础篇】Go语言 init函数详解:包的初始化与应用

介绍

在Go语言中,init() 函数是一种特殊的函数,用于在包被导入时执行一次性的初始化操作。init() 函数不需要手动调用,而是在包被导入时自动执行。这使得我们可以在包导入时完成一些必要的初始化工作,确保包的使用具有正确的环境和状态。

本篇博客将深入探讨 init() 函数的作用、调用时机、使用方式以及一些实际应用场景。通过理解和掌握 init() 函数,您将能够更好地利用它来进行包的初始化和配置,提高代码的可维护性和可靠性。

init() 函数的基本概念

作用与调用时机

init() 函数是一种在Go语言中用于执行初始化操作的特殊函数。每个包可以包含多个 init() 函数,它们会在包被导入时按照顺序自动执行。init() 函数的调用时机为:

  1. 当包被导入时,init() 函数会按照导入的顺序自动执行。
  2. 同一个包中的多个 init() 函数按照编写的顺序执行。

需要注意的是,虽然 init() 函数在包被导入时自动执行,但它们并不会被外部调用。这与其他函数不同,其他函数需要显式地被调用才能执行。

使用方式

init() 函数的使用方式相对简单,它的定义和普通函数类似,只是函数名为 initinit() 函数没有参数和返回值,不需要手动调用,而是在包被导入时自动执行。

package mypackageimport "fmt"func init() {fmt.Println("mypackage 初始化")
}

在上面的示例中,当 mypackage 包被导入时,会自动执行 init() 函数,输出 “mypackage 初始化”。

init() 函数的应用场景

初始化配置信息

init() 函数常用于初始化包的配置信息。例如,当包提供某些服务时,可以在 init() 函数中读取配置文件,进行初始化设置,以便服务能够在正常环境下运行。

package configimport ("fmt""os"
)var Config map[string]stringfunc init() {// 读取配置文件,初始化 Config 变量configFile := "config.ini"Config = make(map[string]string)file, err := os.Open(configFile)if err != nil {fmt.Println("配置文件读取失败:", err)return}defer file.Close()// 将配置信息解析到 Config 变量中// ...
}

数据库初始化

在一些应用中,数据库的初始化通常在包被导入时进行。init() 函数可以用于建立数据库连接,进行必要的数据表创建等操作。

package databaseimport ("database/sql"_ "github.com/go-sql-driver/mysql"
)var DB *sql.DBfunc init() {// 建立数据库连接var err errorDB, err = sql.Open("mysql", "username:password@tcp(localhost:3306)/mydb")if err != nil {panic("数据库连接失败:" + err.Error())}// 创建数据表_, err = DB.Exec(`CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50),email VARCHAR(50))`)if err != nil {panic("数据表创建失败:" + err.Error())}
}

注册功能插件

某些情况下,包中可能存在多个功能插件,这些插件需要在包被导入时注册到主程序中。init() 函数可以用于执行插件的注册操作。

package pluginvar plugins []func()func init() {plugins = append(plugins, func() {// 注册插件1的功能})plugins = append(plugins, func() {// 注册插件2的功能})
}func RunPlugins() {for _, p := range plugins {p()}
}

在上述示例中,init() 函数用于注册两个插件的功能,然后通过 RunPlugins() 函数执行已注册的插件。

init() 函数的注意事项

虽然 init() 函数是方便的初始化工具,但也需要注意一些事项:

执行顺序

同一个包中的多个 init() 函数按照编写的顺序依次执行。在导入包时,它们的调用顺序与导入顺序相同。

不应该被调用

init() 函数不需要手动调用,它会在包被导入时自动执行。不应当在代码中尝试显式调用 init() 函数。

不能返回值

init() 函数不能有返回值,其返回值会被忽略。这与其他函数不同,其他函数的返回值是可以被接收和使用的。

避免过于复杂的操作

尽管可以在 init() 函数中执行一些初始化操作,但应当避免过于复杂和耗时的操作,以免影响导入包的性能和效率。

总结

init() 函数是Go语言中一种特殊的函数,用于在包被导入时执行一次性的初始化操作。它的作用范围广泛,可以用于初始化配置信息、建立数据库连接、注册功能插件等。通过理解和应用 init() 函数,我们可以在包被导入时执行必要的初始化工作,提高代码的可维护性和可靠性。

在使用 init() 函数时,需要注意它的调用时机、使用方式以及一些注意事项。合理地利用 init() 函数,能够在项目中实现更灵活、更模块化的初始化和配置流程。

不同包的 init() 函数执行顺序是由导入顺序决定的,这意味着如果一个包的初始化依赖于另一个包,确保正确的导入顺序是很重要的。避免循环导入,确保包之间的依赖关系是合理的,这可以保证 init() 函数的执行顺序是按照预期的。

尽管 init() 函数可以执行一些必要的初始化操作,但应当避免在其中进行过于复杂和耗时的操作。因为 init() 函数会在包被导入时自动执行,如果执行过程太复杂,可能会影响导入的性能和效率。应当将复杂的操作放在真正需要的地方,以保持 init() 函数的简洁性和高效性。

对于全局变量的初始化,init() 函数也是一个很好的选择。通过在 init() 函数中初始化全局变量,可以确保它们在包被导入时具有正确的初始值,避免在使用时出现未初始化的情况。

在一些情况下,init() 函数可以用于实现一些类似单例模式的功能。通过在 init() 函数中进行一次性的初始化,可以保证在整个程序生命周期中只有一个实例被创建。

总之,init() 函数是Go语言中用于包的初始化操作的重要工具。它使得在包被导入时执行初始化操作变得非常方便,有助于提高代码的可维护性和稳定性。在使用 init() 函数时,应当注意其调用顺序、避免复杂操作、合理利用全局变量的初始化以及保持代码的简洁性。通过合理地应用 init() 函数,您可以更好地管理包的初始化和配置,为项目开发提供更强大的支持。

相关文章:

【Go 基础篇】Go语言 init函数详解:包的初始化与应用

介绍 在Go语言中,init() 函数是一种特殊的函数,用于在包被导入时执行一次性的初始化操作。init() 函数不需要手动调用,而是在包被导入时自动执行。这使得我们可以在包导入时完成一些必要的初始化工作,确保包的使用具有正确的环境…...

wazuh环境配置及漏洞复现

目录 一、wazuh配置 1进入官网下载OVA启动软件 2.虚拟机OVA安装 二、wazuh案例复现 1.wazuh初体验 2.这里我们以SQL注入为例,在我们的代理服务器上进行SQL注入,看wazuh如何检测和响应 一、wazuh配置 1进入官网下载OVA启动软件 Virtual Machine (O…...

Java接收前端请求体方式

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 文章目录 RequestBodyPathVariableRequestParamValidated方法参数校验方法返回值校验 RequestHeaderHttpServletRequest ## Java接收前端请求体的方式 请求体&#xf…...

私有化部署即时通讯平台,30分钟替换钉钉和企业微信

随着企业对即时通讯和协作工具的需求不断增长,私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌,以其安全高效的私有化部署即时通讯解决方案,帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…...

如何深入理解 Node.js 中的流(Streams)

Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念,它能够实现高效的数据处理,特别是在处理大量信息或实时处理数据时。 在本文中,我们将探讨Node.js中的流…...

MSP430FR2xxx开发(一)添加driverlib

一、新建工程 根据自己手上的硬件型号新建工程,文中已MSP430FR2355为例。 二、添加driverlib 首先去官方下载driverlib. https://www.ti.com.cn/tool/cn/MSPDRIVERLIB?keyMatchMSP430%20DRIVERLIB#downloads 下载后的内容如下: 我这里就选择MSP430…...

【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧

[导读]本系列博文内容链接如下: 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…...

34.SpringMVC获取请求参数

SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 index.html <form th:action"{/test/param}" method"post">用户名&#…...

TC1016-同星4路CAN(FD),2路LIN转USB接口卡

TC1016是同星智能推出的一款多通道CAN&#xff08;FD&#xff09;和LIN总线接口设备&#xff0c;CANFD总线速率最高支持8M bps&#xff0c;LIN支持速率0~20K bps&#xff0c;产品采用高速USB2.0接口与PC连接&#xff0c;Windows系统免驱设计使得设备具备极佳的系统兼容性。 支…...

Android源码——从Looper看ThreadLocal

1 概述 ThreadLocal用于在当前线程中存储数据&#xff0c;由于存储的数据只能在当前线程内使用&#xff0c;所以自然是线程安全的。 Handler体系中&#xff0c;Looper只会存在一个实例&#xff0c;且只在当前线程使用&#xff0c;所以使用ThreadLocal进行存储。 2 存储原理 …...

16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及JDBC示例(4)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…...

MySQL 自定义 split 存储过程

MySQL 没有提供 split 函数&#xff0c;但可以自己建立一个存储过程&#xff0c;将具有固定分隔符的字符串转成多行。之所以不能使用自定义函数实现此功能&#xff0c;是因为 MySQL 的自定义函数自能返回标量值&#xff0c;不能返回多行结果集。 MySQL 8&#xff1a; drop pr…...

专题-【十字链表】

有向图的十字链表表示法&#xff1a;...

微信小程序教学系列(2)

第二章&#xff1a;小程序开发基础 1. 小程序页面布局与样式 在小程序开发中&#xff0c;我们可以使用 WXML&#xff08;WeiXin Markup Language&#xff09;和 WXSS&#xff08;WeiXin Style Sheet&#xff09;来定义页面的布局和样式。 1.1 WXML基础 WXML 是一种类似于 H…...

社科院与美国杜兰大学金融管理硕士项目——畅游于金融世界

随着社会经济的不断发展&#xff0c;职场竞争愈发激烈&#xff0c;很多同学都打算通过报考研究生来实现深造&#xff0c;提升自己的综合能力和竞争优势&#xff0c;获得优质的证书。而对于金融专业的学生和在职人员来说&#xff0c;社科院与美国杜兰大学金融管理硕士项目是一个…...

功能强大、超低功耗的STM32WL55JCI7、STM32WL55CCU7、STM32WL55CCU6 32位无线远距离MCU

STM32WL55xx 32位无线远距离MCU嵌入了功能强大、超低功耗、符合LPWAN标准的无线电解决方案&#xff0c;可提供LoRa、(G)FSK、(G)MSK和BPSK等各种调制。STM32WL55xx无线MCU的功耗超低&#xff0c;基于高性能Arm Cortex-M4 32位RISC内核&#xff08;工作频率高达48MHz&#xff09…...

【自适应稀疏度量方法和RQAM】疏度测量、RQAM特征、AWSPT和基于AWSPT的稀疏度测量研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

sql递归查询

一、postgresql 递归sql with recursive p as(select t1.* from t_org_test t1 where t1.id2union allselect t2.*from t_org_test t2 join p on t2.parent_idp.id) select id,name,parent_id from p; sql中with xxxx as () 是对一个查询子句做别名&#xff0c;同时数据库会对…...

常见前端面试之VUE面试题汇总三

7. Vue 中封装的数组方法有哪些&#xff0c;其如何实现页面更新 在 Vue 中&#xff0c;对响应式处理利用的是 Object.defineProperty 对数据进 行拦截&#xff0c;而这个方法并不能监听到数组内部变化&#xff0c;数组长度变化&#xff0c;数 组的截取变化等&#xff0c;所以需…...

Three.js 实现模型材质分解,拆分,拆解效果

原理&#xff1a;通过修改模型材质的 x,y,z 轴坐标 positon.set( x,y,z) 来实现拆解&#xff0c;分解的效果。 注意&#xff1a;支持模型材质position 修改的材质类型为 type“Mesh” ,其他类型的材质修改了position 可能没有实际效果 在上一篇 Three.js加载外部glb,fbx,gltf…...

《JVM修仙之路》初入JVM世界

《JVM修仙之路》初入JVM世界 博主目前正在学习JVM的相关知识&#xff0c;想以一种不同的方式记录下&#xff0c;娱乐一下 清晨&#xff0c;你睁开双眼&#xff0c;看到刺眼的阳光&#xff0c;你第一反应就是完了完了&#xff0c;又要迟到了。刚准备起床穿衣的你突然意识到不对&…...

苍穹外卖 day1 搭建成功环境

引入 idea找不到打包生成的文件目录怎么办&#xff0c;首先点击这个小齿轮 show ecluded files然后就能找到隐藏的文件 这个jar包内含tomcat&#xff0c;可以直接丢在linux上用 开发环境&#xff1a;开发人员在开发阶段使用的环境&#xff0c;一般外部用户无法访问 测试环…...

智能主体按照功能划分

(1) 构件接口主体 构件接口主体提供构件与用户之间的接口。当一个用户通过代理主体向 元组空间提出申请&#xff0c;并找到相匹配的构件主体时&#xff0c;此构件主体会将其所在构件主体 组中的构件接口主体通过申请用户的代理主体传送到用户的界面。 (2) 构件主体 通过构…...

python中的matplotlib画折线图(数据分析与可视化)

先导包&#xff08;必须安装了numpy 、pandas 和matplotlib才能导包&#xff09;&#xff1a; import numpy as np import pandas as pd import matplotlib.pyplot as plt核心代码&#xff1a; import numpy as np import pandas as pd import matplotlib.pyplot as pltpd.se…...

大数据数据仓库

一.在线教育 1.数据采集 1.数仓概念 数据仓库是为企业制定决策&#xff0c;提供数据支持的。数据采集和存储、对数据进行计算和分析 2.项目架构 2.数据分类 业务数据 用户行为数据 爬虫数据 2.离线数仓 3.实时数仓...

Java“牵手“速卖通商品详情页面数据获取方法,速卖通API实现批量商品数据抓取示例

速卖通商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取速卖通商品详情数据&#xff0c;您可以通过开放平台的接口或者直接访问速卖通商城的网页来获取商品详情信息。以下是两种常用方法的介绍&#xff1a;…...

【Git】代码误推送还原(真实项目环境,非纸上谈兵)

背景 RT&#xff0c; 我今天眼睛花了&#xff0c;不小心把工作分支【合并】到了一个不相干的功能分支上&#xff0c;并且代码已经推送到远程仓库了。于是&#xff0c;只能尝试还原到上一次提交中。 【合并】分支有一个点我们是不可避免的&#xff0c;文字很难描述&#xff0c;…...

CPU 飙升?这3大场景助你精准定位

1 常用的 Load 分析方法 CPU高、Load高 通过 top 命令查找占用CPU最高的进程PID&#xff1b; 通过top -Hp PID查找占用CPU最高的线程TID; 对于java程序&#xff0c;使用jstack打印线程堆栈信息&#xff1b; 通过printf %x tid打印出最消耗CPU线程的十六进制&#xff1b; …...

6、Spring_Junit与JdbcTemplate整合

Spring 整合 1.Spring 整合 Junit 1.1新建项目结构 1.2导入依赖 导入 junit 与 Spring 依赖 <!-- 添加 spring 依赖--> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version…...

Redis是如何保证高可用的?

Redis这种基于内存的关系型数据库我们在选用的时候就是考虑到它的快。而且可以很方便的实现诸如分布式锁、消息队列等功能。 笔者在前一段秋招面试的时候就被提问&#xff0c;“Redis是怎么保证高可用的&#xff1f;” 后续的子问题包含&#xff0c;集群模式是怎么实现的&…...

博客园网站开发/百度一下网页版浏览器

https://blog.csdn.net/q5706503/article/details/82910428 首先要明确的是JAVA中没有引用传递, 全部是按值调用 令大家所费解的 当对象引用作为参数时 函数为什么能修改真实的对象呢?这不是引用传递的特征吗? 尤其先学习C再学习JAVA的同学(比如说我自己)会这样认为, 用…...

wordpress contact 插件/搜索seo是什么意思

定义&#xff08;#86debe&#xff09; 组合&#xff1a;C(n,m)表示从n个元素中&#xff0c;取任意的m个元素的方案数。 定义式&#xff1a;    递推式&#xff1a;C(n,m)C(n-1,m-1)C(n-1,m) 排列&#xff1a;A(n,m)表示从n个元素中&#xff0c;取任意的m个元素并排列好的方…...

免费logo设计生成器下载/快速排名优化公司

本课件包含的主要内容为&#xff1a; 研究动机&#xff1a;稀疏正则化 次梯度与次微分 L1正则化问题的次微分 练习&#xff1a;次梯度方法 次梯度的替代方法 近端梯度法 近端算子的有用特性 非平滑优化的最速下降 英文原文课件下载地址&#xff1a; http://page2.dfpa…...

1688网站店招怎么做/搜索引擎营销的案例

其实说来是非常简单。window.onload abc();改成window.onload function (){ abc();}真不知道为什么。希望能知道原因的高人们告诉小弟&#xff0c;为什么 加个function{}就可以了。...

有没有做任务给钱的网站/网络营销公司是做什么的

原标题&#xff1a;IC卡无人值守称重系统操作流程IC卡无人值守称重系统包括基本数据管理和系统平台管理&#xff0c;是宏树电子自主开发的一套通过IC卡识别无人智能称重管理系统。IC卡无人值守称重系统基本数据管理分为&#xff1a;1.称重数据管理2.皮重管理3.采购管理4.销售管…...

国际抖抈2022/长沙网站seo报价

目录一、switch语句1. 输入等级、输出分数范围2. 输入成绩、输出分数范围二、if语句1. 输入等级、输出分数范围一、switch语句 1. 输入等级、输出分数范围 switch语句实现&#xff1a;多分支选择结构 题目&#xff1a;要求按照考试成绩的等级输出百分制分数段&#xff0c;A等…...