首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
c语言
solr
join
char
substring
bitmap
cookie
dll
schema
post
copy
io
express
scala
hashset
input
select
timestamp
main
range
go
int
buffer
runtime
process
config
uml
include
jsp
controller
web3
case
eval
tree
timezone
golang
bash
jar
instance
javascript
utf-8
rsa
replace
cSharp
erlang
bit
netty
audio
import
python3
vba
list
python
web
match
byte
flutter
ascii
sum
loops
nodejs
client
subset
md5
function
dagger
const
integer
uri
lua
less
usb
window
require
emoji
frameworks
get
shell
regex
当前位置:
开发笔记
>
编程语言
> 正文
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
文件
编译
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
int
Java在PDF文档中添加或删除页面
当你编辑一个PDF文档时,有时需要删除文档中多余的页面或 ...
[详细]
蜡笔小新 2024-09-27 14:29:44
int
Proof (of knowledge) of exponentiation
1.ProofofexponentiationProofofexponentiation是基于adaptiverootassumption(充分必要条件 ...
[详细]
蜡笔小新 2024-09-27 15:32:38
int
如何实现Percona Mysql Galera多读写集群的部署
本篇文章给大家主要讲的是关于如何实现PerconaMysqlGalera多读写集群的部署的内容,感兴趣的话就一起来看看这篇文章吧,相信看完如何实现PerconaMysq ...
[详细]
蜡笔小新 2024-09-27 14:40:41
include
《数据结构上机实验(C语言实现)》笔记(1 / 12):绪论
文章目录验证性实验求1~n的连续整数和说明放码结果常见算法时间函数的增长趋势分析说明放码结果设计性实验求素数个数说明放码结果求连续整数阶乘的和说明放码结果验证性实验求1~n的连续 ...
[详细]
蜡笔小新 2024-09-27 14:32:28
include
linux ipc——shared memory
1、概念共享内存:共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同malloc()函数向不同进程返回了指向同一个 ...
[详细]
蜡笔小新 2024-09-27 11:39:50
process
Electron中globalShortcut模块注册全局快捷键
Electron中使用globalShortcut模块来注册全局快捷键,以实现类似于微信和QQ按快捷键调用剪切窗口的功能。快捷键在应用程序加载完成后进行注册 ...
[详细]
蜡笔小新 2024-09-27 08:08:34
controller
springboot系列(二)创建springboot工程
https:www.cnblogs.commagicalSamp7171716.html简介SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spri ...
[详细]
蜡笔小新 2024-09-27 04:29:57
int
数据库的存储结构及其重要性
本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ...
[详细]
蜡笔小新 2023-12-14 16:00:02
int
sklearn数据集库中的常用数据集类型介绍
本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ...
[详细]
蜡笔小新 2023-12-13 17:45:15
int
Android 7自学笔记总结、移动架构视频、安卓面试真题、项目实战源码讲义
本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ...
[详细]
蜡笔小新 2023-12-13 10:06:58
int
深度学习中的Vision Transformer (ViT)详解
本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ...
[详细]
蜡笔小新 2023-12-12 15:26:38
go
详解 Python 的二元算术运算,为什么说减法只是语法糖?[Python常见问题]
原题|UnravellingbinaryarithmeticoperationsinPython作者|BrettCannon译者|豌豆花下猫(“Python猫 ...
[详细]
蜡笔小新 2023-10-17 15:28:24
int
Python如何调用类里面的方法
本文介绍了在Python中调用同一个类中的方法需要加上self参数,并且规范写法要求每个函数的第一个参数都为self。同时还介绍了如何调用另一个类中的方法。详细内容请阅读剩余部分。 ...
[详细]
蜡笔小新 2023-12-14 12:52:55
int
Java中闭包的争论以及闭包的定义和特性
闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ...
[详细]
蜡笔小新 2023-12-13 10:46:54
include
RT3070无线网卡STA模式并使开发板接入Wifi上网
开发板:FL2440内核:linux3.0无线网卡:RT3070RT3070的工作模式分为STA(station)模式、SoftAP(AccessPoint)模式两种。STA ...
[详细]
蜡笔小新 2023-10-16 19:01:18
暖暖252
这个家伙很懒,什么也没留下!
Tags | 热门标签
c语言
solr
join
char
substring
bitmap
cookie
dll
schema
post
copy
io
express
scala
hashset
input
select
timestamp
main
range
go
int
buffer
runtime
process
config
uml
include
jsp
controller
RankList | 热门文章
1
win10怎么更改系统显示字体效果
2
C/C++语言void及void指针
3
鼓励 压力 悲伤
4
JSON 转 javaBean
5
hdoj1049解题报告
6
消息中间件Activemq之BrokerCluster
7
spring boot获取datasource为null_SpringBoot运行源码分析:Spring应用上下文创建
8
PHP中的类-邮件群发
9
《送菊潭王明府》翻译 原文赏析诗人唐司空曙
10
Python快速编程入门#学习笔记01# |第一章 :Python概述 (Python发展历程、开发工具、模块)
11
EditPlus正确配置java运行环境,用appletviewer运行applet小程序。
12
ES6之函數的擴大(一)
13
转:Java Ant build.xml详解
14
PDF转化成Word网站推荐
15
为什么论坛一般用PHP,为什么我要用phpwind代替discuz
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有