首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
copy
shell
dll
version
bash
tags
expression
cmd
command
string
timestamp
hashset
php
cPlusPlus
golang
sum
integer
merge
md5
char
go
import
stream
nodejs
instance
match
erlang
hashcode
utf-8
request
tree
数组
vbscript
range
byte
perl
join
schema
netty
function
subset
typescript
iostream
less
usb
cSharp
spring
controller
scala
io
actionscrip
config
post
php8
audio
cookie
int
bit
js
frameworks
web3
process
fetch
get
main
input
triggers
metadata
select
window
settings
case
python
solr
jsp
list
heap
split
python2
当前位置:
开发笔记
>
编程语言
> 正文
Go中的init函数
作者:暖暖252 | 来源:互联网 | 2024-09-27 15:01
main 标识符是随处可见的,每一个 Go 程序都是从一个叫 main 的包中的 main 函数开始的,当 main 函数返回时,程序执行结束。 init 函数也扮演着特殊的角色,接下来我们将描述下 init 函数的属性并介绍下怎么使用它们。
init 函数在包级别被定义,主要用于:
- 初始化那些不能被初始化表达式完成初始化的变量
- 检查或者修复程序的状态
- 注册
- 仅执行一次的计算
- 更多其它场合
除了下面将要讨论到的一些差异外,你还可以在正则函数中放置任何[有效](https://golang.org/ref/spec#FunctionBody)的内容。
## 包的初始化
要想使用导入的包首先需要初始化它,这是由golang的运行系统完成的,主要包括(顺序很重要):
1. 初始化导入的包(递归的定义)
2. 在包级别为声明的变量计算并分配初始值
3. 执行包内的 init 函数(下面的空白标识符就是一个例子)
> 不管包被导入多少次,都只会被初始化一次。
## 顺序
Go 的包中有很多的文件,如果变量和函数在包的多个文件当中,那么变量的初始化和 init 函数的调用顺序又是什么样的呢?首先,初始化依赖机制会启动(更多 [Go 中的初始化依赖](https://studygolang.com/articles/13158))当初始化依赖机制完成的时候,就需要决定 `a.go` 和 `z.go` 中的初始化变量谁会被更早的处理,而这要取决于呈现给编译器的文件顺序。如果 `z.go` 先被传递到构建系统,那么变量的初始化就会比在 `a.go` 中先一步完成,这也同样适用于 init 函数的触发。Go 语言规范建议我们始终使用相同的顺序传递,即按照词法顺序传递包中的文件名:
> 为了保证可重复的初始化行为,构建系统鼓励按照词法文件名的顺序将属于同一个包中的多个文件呈现给编译器。
但依赖特定顺序对于不关注可移植性的程序是一种方式(译注:但不建议依赖 init 初始化顺序)。让我们来看一个例子,看看它们是如何一起工作的:
### sandbox.go
```go
package main
import "fmt"
var _ int64 = s()
func init() {
fmt.Println("init in sandbox.go")
}
func s() int64 {
fmt.Println("calling s() in sandbox.go")
return 1
}
func main() {
fmt.Println("main")
}
```
### a.go
```go
package main
import "fmt"
var _ int64 = a()
func init() {
fmt.Println("init in a.go")
}
func a() int64 {
fmt.Println("calling a() in a.go")
return 2
}
```
### z.go
```go
package main
import "fmt"
var _ int64 = z()
func init() {
fmt.Println("init in z.go")
}
func z() int64 {
fmt.Println("calling z() in z.go")
return 3
}
```
### 程序输出:
```
calling a() in a.go
calling s() in sandbox.go
calling z() in z.go
init in a.go
init in sandbox.go
init in z.go
main
```
## 属性
init 函数不需要参数并且也不返回任何值,与 main 类似,标识符 init 没有被声明所以也就不能被引用:
```go
package main
import "fmt"
func init() {
fmt.Println("init")
}
func main() {
init()
}
```
在编译时这里会给出一个 “undefined:init” 错误。( init 函数不能被引用)
> 正式的来讲 init 标示符不会引入绑定,就像空白标示符('_')表现的一样。
在同一个包或者文件当中可以定义很多的 init 函数:
### sandbox.go
```go
package main
import "fmt"
func init() {
fmt.Println("init 1")
}
func init() {
fmt.Println("init 2")
}
func main() {
fmt.Println("main")
}
```
### utils.go
```go
package main
import "fmt"
func init() {
fmt.Println("init 3")
}
```
### 输出:
```
init 1
init 2
init 3
main
```
init 函数在标准库中也被频繁的使用,例如:[*main*](https://github.com/golang/go/blob/2878cf14f3bb4c097771e50a481fec43962d7401/src/math/pow10.go#L33), [*bzip2*](https://github.com/golang/go/blob/2878cf14f3bb4c097771e50a481fec43962d7401/src/compress/bzip2/bzip2.go#L479)还有 [*image*](https://github.com/golang/go/blob/2d573eee8ae532a3720ef4efbff9c8f42b6e8217/src/image/gif/reader.go#L511)包。
...
init 函数最常见的用法就是为初始化表达式中不能被计算的那部分分配一个值:
```go
var precomputed = [20]float64{}
func init() {
var current float64 = 1
precomputed[0] = current
for i := 1; i
precomputed[i] = precomputed[i-1] * 1.2
}
}
```
使用 for 循环作为[*表达式*](https://golang.org/ref/spec#Expression)(Go 语言中的语句)是不可能的,所以将这些放到 init 函数中就能够很好的解决这些问题。
## 仅仅为了使用包的副作用(包的初始化)而导入包
Go 语言对没有使用的导入是非常严格的。有时候程序员导入一个包可能只想要使用 init 函数的功能,例如一些引导工作。空白标示符就是一个不错的方式:
```go
import _ "image/png"
```
它甚至在[*image*](https://github.com/golang/go/blob/0104a31b8fbcbe52728a08867b26415d282c35d2/src/image/image.go#L10)包中被提到。
如果上面的内容对你有所帮助请跟随我一起续写未来的故事吧,那也将成为我的动力。
---
## 参考资料
- [The Go Programming Language Specification - The Go Programming Language](https://golang.org/ref/spec#Package_initialization)
- [Blocks in Go](https://studygolang.com/articles/12632)
- [Initialization dependencies in Go](https://studygolang.com/articles/13158)
go
text
main
正则
https
c#
function
文件
编译
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
go
网络链路质量监控:Smokeping部署与配置
本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ...
[详细]
蜡笔小新 2024-12-27 19:31:05
import
Python 的 10 个开发技巧!太实用了
1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ...
[详细]
蜡笔小新 2024-12-27 18:36:54
import
Go语言基础:Hello World 实践
本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ...
[详细]
蜡笔小新 2024-12-27 21:29:35
char
CentOS7源码编译安装MySQL5.6
2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ...
[详细]
蜡笔小新 2024-12-27 17:49:56
char
JQuery基础:省市联动与表单验证
本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ...
[详细]
蜡笔小新 2024-12-27 17:10:48
request
Yii2 GridView 实现列表页数据直接编辑的完整指南
本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ...
[详细]
蜡笔小新 2024-12-27 16:27:52
php
解决PHP与MySQL连接时出现500错误的方法
本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ...
[详细]
蜡笔小新 2024-12-27 15:48:52
char
Java面试题解析
本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ...
[详细]
蜡笔小新 2024-12-27 13:55:14
char
Ionic 5 APK打包与QRScanner插件优化:常见问题及解决方案
本文总结了在使用Ionic 5进行Android平台APK打包时遇到的问题,特别是针对QRScanner插件的改造。通过详细分析和提供具体的解决方法,帮助开发者顺利打包并优化应用性能。 ...
[详细]
蜡笔小新 2024-12-27 12:10:17
utf-8
XNA 3.0 游戏编程:从 XML 文件加载数据
本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ...
[详细]
蜡笔小新 2024-12-27 11:39:44
utf-8
深入探讨JSP技术的优缺点
本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ...
[详细]
蜡笔小新 2024-12-28 11:00:33
utf-8
解决Uploadify在IE浏览器中的兼容性问题
本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ...
[详细]
蜡笔小新 2024-12-27 22:07:40
instance
新浪笔试题
1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ...
[详细]
蜡笔小新 2024-12-27 19:32:17
php
PHP 5.2.5 安装与配置指南
本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ...
[详细]
蜡笔小新 2024-12-27 19:05:41
import
Java并发编程:LinkedBlockingQueue的实际应用
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
暖暖252
这个家伙很懒,什么也没留下!
Tags | 热门标签
copy
shell
dll
version
bash
tags
expression
cmd
command
string
timestamp
hashset
php
cPlusPlus
golang
sum
integer
merge
md5
char
go
import
stream
nodejs
instance
match
erlang
hashcode
utf-8
request
RankList | 热门文章
1
Vue 开发与调试工具指南
2
Java中的基本数据类型与包装类解析
3
优化Jenkins首次启动速度
4
Django 使用slug field时遇到的问题
5
大雾引发的养蚕危机
6
Java中罗马数字计算器的字符验证与循环输入处理
7
GoCV入门指南:配置与基础应用
8
MySQL DATETIME 类型长度及使用指南
9
Django Token 认证详解与 HTTP 401、403 状态码的区别
10
深入探讨Web页面中的锚点交互设计
11
JavaScript 数组数据的合并与处理
12
Java 中的不可变集合与同步集合详解
13
正则表达式:匹配包含转义双引号的中文内容
14
openGauss每日一练第 12 天 |学习openGauss定义数据类型
15
图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(qt + 不调包)
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有