Init函数和main函数
init
函数
先理解一个点:go语言中init
函数用于包(package)
的初始化,该函数是go语言的一个重要特性。
“_”是特殊标识符,用来忽略结果。
在Golang里,import的作用是导入其他package。
import 下划线(如:import _ hello/imp)的作用:
当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。
这个时候就可以使用 import _ 引用该包。即使用【import _ 包路径】只是引用该包,仅仅是为了调用init()函数,所以无法通过包名来调用包中的其他函数。
init函数有下面的特征:
1 init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
2 每个包可以拥有多个init函数
3 包的每个源文件也可以拥有多个init函数
4 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
5 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
6 init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
main
函数
Go语言程序的默认入口函数(主函数):func main()
函数体用{}一对括号包裹。
func main(){
//函数体
}
两个函数的执行顺序:
对同一个go文件的init()
调用顺序是从上到下的。
对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()
函数。
对于不同的package
,如果不相互依赖的话,按照main包中”先import
的后调用”的顺序调用其包中的init()
,如果package
存在依赖,则先调用最早被依赖的package
中的init()
,最后调用main
函数。
如果init
函数中使用了println()
或者print()
你会发现在执行过程中这两个不会按照你想象中的顺序执行。这两个函数官方只推荐在测试环境中使用,对于正式环境不要使用。
Hello world实例
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
编译 + 运行
go run hello.go
Hello, World!
go run 做了编译和执行两动作,编译会生成 hello 文件,执行完成后此文件会被删除。
web展示
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, World!")
})
fmt.Println("Please Visit - http://localhost:8899/")
http.ListenAndServe(":8899", nil)
}
-
Golang 中常见的变量定义方法如下:
1、var 定义变量
var 变量名 类型 = 表达式(类型可以不需要添加,自带类型推导)
package main
import "fmt"
func main(){
//1.变量的声明
var age int
//2.变量的赋值
age = 18
//3.变量的使用
fmt.Println("age = ",age);
//声明和赋值可以合成一句:
var age2 int = 19
fmt.Println("age2 = ",age2);
// var age int = 20;
// fmt.Println("age = ",age);
}
2、类型推导方式定义变量
![](https://i-blog.csdnimg.cn/blog_migrate/99f8b64cfed340689a2c1e2ca3bf44ed.png)
![](https://i-blog.csdnimg.cn/blog_migrate/695f430304b3039e2a8ae23f165e49d8.png)
变量名 := 表达式(注意:冒号和=要挨着 冒号前和等于号后空格 美观)
![](https://i-blog.csdnimg.cn/blog_migrate/72c313b6eda5f81cdecec62c58e4ad16.png)
package main
import "fmt"
func getuser() (string, int) {
return "远坂凛",10
}
func main(){
// var username = "卫宫士郎"
// fmt.Println(username)
// var (
// username string = "卫宫士郎"
// age int = 20
// sex string = "男"
// )
// fmt.Println(username,age,sex)
// 变量命名法
// 变量不能重复命名,但是可以重复赋值
var username,age = getuser()
fmt.Println(username,age)
// 短变量命名法
a,b,c := 19,20,"archer"
fmt.Printf("%v.%v,%v",a,b,c)
}
支持一次性声明多个变量(多变量声明)
package main
import "fmt"
//全局变量:定义在函数外的变量
var boyname = "卫宫士郎"
var boyage = 19
//全局变量一次性声明:
var (
girlage = 20
girlname = "远坂樱"
)
func main(){
//定义在{}中的变量叫:局部变量
//第一种:变量的使用方式:指定变量的类型,并且赋值,
var num int = 22
fmt.Println(num)
//第二种:指定变量的类型,但是不赋值,使用默认值
var num2 int
fmt.Println(num2)
//第三种:如果没有写变量的类型,那么根据=后面的值进行判定变量的类型 (自动类型推断)
var num3 = "Archer"
fmt.Println(num3)
//第四种:省略var,注意 := 不能写为 =
sex := "男"
fmt.Println(sex)
fmt.Println("------------------------------------------------------------------")
//声明多个变量:
var a,b,c int
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
var d,name,e = 10,"sabar",169
fmt.Println(d)
fmt.Println(name)
fmt.Println(e)
garde,height := 6.9,100.6
fmt.Println(garde)
fmt.Println(height)
fmt.Println(boyname)
fmt.Println(boyage)
fmt.Println(girlage)
fmt.Println(girlname)
}
匿名变量
![](https://i-blog.csdnimg.cn/blog_migrate/f79beb28f4155bfc148d9bbb8a7b35c0.png)
package main
import "fmt"
func varinfo()(string,int){
return "远坂凛",21
}
func main() {
name,age := varinfo()
fmt.Printf("MY name is %v,age is %v",name,age)
}
![](https://i-blog.csdnimg.cn/blog_migrate/5be38c4013ef6763c5deb29d91da4d95.png)
package main
import "fmt"
func varinfo()(string,int){
return "远坂凛",21
}
func main() {
_,age := varinfo()
fmt.Printf("age is %v",age)
}
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。
注意事项:
-
fmt 包、Print、Println、Printf
import "fmt"fmt 包里面给我们提供了一些常见的打印数据的方法,比如: Print 、 Println 、 Printf , 在我们实际开发中 Println 、 Printf 用的非常多。
1、Print 和 Println 区别:
![](https://i-blog.csdnimg.cn/blog_migrate/e76cee78c4f12df26c55a56a20d226e6.png)
Println 会自动换行,Print 不会
![](https://i-blog.csdnimg.cn/blog_migrate/dab73a5192bfd463da49031ec526cb53.png)
2、Println 和 Printf 区别:
![](https://i-blog.csdnimg.cn/blog_migrate/59c253f1669bc787d56cb6c8278a0145.png)
package main
import "fmt"
func main() {
var(
name = "卫宫士郎"
age = 19
servant = "sabar"
)
fmt.Println("我的名字是:" ,name,"年龄:",age,"servant为:",servant)
fmt.Printf("我的名字是%v,年龄为%v,servant为%v",name,age,servant)
}
Printf 中的占位符与后面的数字变量一一对应。例如: %d 是占位符,表示数字的十进制表示。
-
Go 语言中的注释
行注释 // VSCode快捷键:ctrl+/ 再按一次取消注释
块注释(多行注释) /**/ VSCode快捷键:shift+alt+a 再按一次取消注释
注意:块注释中不可以嵌套块注释
-
Go 语言中的常量
相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var
换成了const
,常量在定义的时候必须赋值。
代码如下:细分
//整体代码
package main
import "fmt"
func main() {
const (
name = "卫宫士郎"
serVant = "SABAR"
age
number
)
const(
a = iota
_
b
c = 100
d = iota
e
)
fmt.Println(name, serVant,age,number,a,b,c,d,e)
}
声明了上面第一个const中的name和servant这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。(多常量声明法)
单常量声明如下:
const name = "奥特曼"
const age = 123124
注意:const
同时声明多个常量时,如果省略了值则表示和上面一行的值相同。
iota
iota
是go
语言的常量计数器,只能在常量的表达式中使用。
iota
在const
关键字出现时将被重置为0
。
const
中每新增一行常量声明将使iota
计数一次(iota
可理解为const
语句块中的行索引)。
使用iota
能简化定义,在定义枚举时很有用。
1、iota 只能在常量的表达式中使用。
fmt.Println(iota) //编译错误: undefined: iota
2、每次 const 出现时,都会让 iota 初始化为 0.【自增长】
package main
import "fmt"
func main() {
const(
a = iota //0
b // 1
c
d
e
)
fmt.Println(a,b,c,d,e)
}
3、const iota 使用_跳过某些值
4、iota 声明中间插队
const
中每新增一行常量声明将使iota
计数一次
4、多个 iota 定义在一行
package main
import "fmt"
func main() {
const (
a, b = iota + 1, iota + 2
c, d
e, f
)
fmt.Println(a,b)
fmt.Println(c,d)
fmt.Println(e,f)
}
const
中每新增一行常量声明将使iota
计数一次
-
Go 语言变量、常量命名规则
- 变量名称必须由数字、字母、下划线组成。
- 标识符开头不能是数字
- 标识符不能是保留字和关键字。
- 变量的名字是区分大小写的如: age 和 Age 是不同的变量。在实际的运用中,也建议,不要用一个单词大小写区分两个变量。
- 标识符(变量名称)一定要见名思意 :变量名称建议用名词,方法名称建议用动词
- 变量命名一般采用驼峰式,当遇到特有名词(缩写或简称,如 DNS)的时候,特有名词根据是否私有全部大写或小写。
-
Go 语言代码风格
- 代码每一行结束后不用写分号( ;)
- 运算符左右建议各加一个空格
var username string = "itying"
- Go 语言程序员推荐使用驼峰式命名当名字有几个单词组成的时优先使用大小写分隔
- 强制的代码风格
go fmt 主要用于格式化文档,让所有人的代码风格保持一致
D:\golang\src\demo01>go fmt main.go
main.go