init初始化函数,会在main函数执行前执行,如果import了其他的包中包含init函数
那么他会优先去扫描导入包中的init函数并执行
package main
import "fmt"
func init() {
fmt.Println("test main init")
}
func main(){
fmt.Println("echo main")
}
返回
test main init
echo main
#init函数会在main之前执行
vi utils/utils.go
package utils
import "fmt"
func init() {
fmt.Println("utils test init")
}
func Test() {
fmt.Println("test")
}
vi main/main.go
package main
import (
"fmt"
"test/utils"
)
func init() {
fmt.Println("main test init")
}
func main(){
utils.Test()
}
返回
utils test init #先去执行了要导入的包的init
main test init #然后执行了main的init函数,所有init执行完毕后,执行main函数
test #通过main函数调用utils包的test函数,输出test
如果一个文件同时包含"全局变量"、"init函数"、 "main 函数"
#则执行的顺序是
全局变量定义--> init函数--> main 函数
当我们只希望一个函数只需要执行一次时,就可以使用匿名函数,当然匿名函数也可以使用多次
func (形参传入) 返回值列表 {
代码块
}(实参)
#和正常的函数类似,只不过去除了函数的名称
#因为没有函数名,无法调用传参,所以直接在{}后面使用括号()进行参数传递
#例如
func (n1 int,n2 int) int{
return n1 + n2
}(10,20)
package main
import "fmt"
func main() {
//在定义匿名函数时直接使用.这种方式匿名函数只能调用一次
//通过匿名函数,我们指定传入了10、20的值给n1、n2
//通过{} 内返回值是n1+n2的和,返回值类型是int
//通过:= 类型推导 赋值给res1
res1 := func (n1 int,n2 int) int{
return n1 + n2
}(10,20)
fmt.Println(res1) //这样的匿名函数只能使用一次,用作临时运算
}
上面的的方法是给匿名函数直接提供参数进行运算,我们可以把匿名函数定义为一个变量 多次使用
package main
import "fmt"
func main() {
a := func (n1 int,n2 int) int{ //我们将这个匿名函数定义给了a变量 (没有设置参数)
return n1 + n2
}
res2 := a(10,20) //此时a变量就可以看作是一个独立的函数,
//通过a()来调用这个函数,可以多次调用
fmt.Println(res2)
}
package main
import "fmt"
var (
//Fun1 是全局变量,我们将一个匿名函数赋给这个变量,他就可以在整个程序中使用了
//如果首字母大小,那么就可以在不同的包中调用该匿名函数
Fun1 = func (n1 int,n2 int) int {
return n1 * n2
}
)
func main() {
res4 := Fun1(10,20) //调用匿名函数
fmt.Println(res4)
}
发现一篇写的很详细的,转一下哈 O(∩_∩)O
Golang中闭包的理解_Erick Lv的笔记-CSDN博客_golang 闭包
package main
import "fmt"
var f = func(int) {} //定义一个匿名函数的变量
func main() {
f = func(i int) { //f可以被任何输入一个整型,并且无返回值的匿名函数给赋值
fmt.Println(i)
}
f(2)
f = func(i int) {
fmt.Println(i * i * i)
}
f(2)
}
匿名函数有动态创建的特性,使得匿名函数不用通过参数传递的方式,就可以直接引用外部的变量。类似常规函数引用全局变量
package main
import "fmt"
func main() {
n := 0 //定义普通变量
f := func() int { //将匿名函数封装为变量
n += 1 //在匿名函数中调用匿名函数外部的变量
//运算会修改外部变量的值
return n
}
fmt.Println(f()) //f()调用匿名函数 去做n += 1的操作
fmt.Println(f()) //通过return n 会将匿名函数计算完的值返回给 n变量
}
返回
1
2
n := 0
f := func() int {
n += 1
return n
}
//上述代码就是一个闭包,类比于常规函数+全局变量+包。
//f不仅仅是存储了一个函数的返回值,它同时存储了一个闭包的状态。
匿名函数作为返回值,不如理解理解为闭包作为函数的返回值,
package main
import "fmt"
func Increase() func() int {
n := 0
ss := func() int {
n++
return n
}
return ss
}
func main() {
in := Increase() //闭包被返回赋予一个同类型的变量时,同时赋值的是整个闭包的状态
//这个状态会一直存在外部被赋值的变量in中
//直到in被消耗,整个闭包也被销毁
fmt.Println(in())
fmt.Println(in())
}
返回
1
2
package main
import "fmt"
func AddUpper() func (int) int {
var n int = 10
ss := func (x int) int {
n = n + x
return n
}
return ss
}
func main() {
f := AddUpper()
fmt.Println(f(1))
fmt.Println(f(2))
}
返回
11
13
编写一个程序,要求如下
1. 编写一个函数makeSuffix(suffix string) 可以接受一个文件后缀名(比如.jpg),并返回一个闭包
2. 调用闭包,可以传入一个文件名,如果文件没有指定的后缀
(比如.jpg) 则返回文件名.jpg,如果已有.jpg后缀,则返回源文件名
3. 要求使用闭包的方式完成
4. strings.HasSuffix(变量,后缀名) #该函数可以判断字符串是否有指定的后缀
package main
import (
"fmt"
"strings"
)
func makeSuffix(suffix string) func(string) string{
return func(name string) string {
if strings.HasSuffix(name,suffix) == false { //strings.HasSuffix判断name字符串的后缀,是否是.jpg
return name + suffix //如果不是,则结尾添加.jpg
}
return name //如果是,则直接返回该名称
}
}
func main() {
f := makeSuffix(".jpg")
//调用闭包,传入参数到name变量
fmt.Println("文件名处理好=",f("winter"))
fmt.Println("文件名处理好=",f("bird.jpg"))
}