一、函数基础
定义:有输入、有输出、用来执行一个指定任务的代码块
func 函数名(形参列表)(返回值列表){
执行代码
return 返回值列表
}
//无参数和返回值
func test(){
fmt.Println("helloWorld")
}
func main(){
test()
}
//函数的多返回值
func test(x,y int,z string) (int,string){
//类型相同的相邻参数x,y参数类型可以合并
//多返回值得用括号括起来
n := x+y
return n,z
}
//返回值进行命名
func test2(a,b int) (sum int,sub int) {
sum = a+b
sub = a-b
return
}
func main(){
sum,sub := test2(100,800)
fmt.Println(sum,sub)
}
//可变参数
func test3(b ...int) int{
sum :=0
for i := 0;i<len(b);i++{
sum = sum + b[i]
}
return sum
}
func main(){
sum := test3(10,20) //可以传任意个参数
fmt.Printf("sum=%d
"),sum)
}
二、函数defer语句
定义:在一个函数中有defer语句时,只有到返回的时候才会执行,多个defer时执行顺序是从后往前,多用于资源脂肪,使用defer关闭资源
func test(){
defer fmt.Println("Hello")
fmt.Println("Parallel")
fmt.Println("World")
)
//结果 Parallel World Hello
func test2(){
defer fmt.Println("Hello")
defer fmt.Println("Hello1")
defer fmt.Println("Hello2")
fmt.Println("Parallel")
fmt.Println("World")
}
//结果 Parallel World Hello2 Hello1 Hello
fun test3(){
for i:=0;i<5;i++{
defer fmt.Println(i)
}
}
//结果 4 3 2 1 0
func test4(){
i := 0
defer fmt.Println(i)
i = 1000
fmt.Println(i)
}
//结果 1000 0 当执行代码到defer时,参数已经传入,但是最后执行
三、内置函数
close:主要用来关闭channel(管道)
len:用来求长度(如:string,array,slice,map,channel)
new:用来初始化int、struct,返回指针 var a = new(int):得到一个int类型的指针
make:用来初始化channel,map,slice
append:用来追加元素到slice
panic和recover:用来做错误处理
变量作用域和可见性
//作用域:全局变量,在函数最外层
var a int = 100
func test(){
fmt.Printf("a = %d
",a)
}
//作用域:局部变量(1.函数内定义2.语句块内定义)
func add(a int,b int) int {
var sum int = 0 //sum是局部变量
if a>0{
var c int = 100 //c是局部变量,只在if语句块有效
}
}
//可见性:包内任何变量或函数都是能访问的,首字母大写是可以导出的,能够被其他包访问或调用,小写表示私有,不能被嗲用
package caic
var a int = 100
var A int = 200
func Add(a,b int) int{
return a+b
}
func sub(a,b int) int{
return a-b
}
package caic
func Test()int{
return a
} //包名相同,可以调用
package main
import ("fmt","caic")
func main(){
var s1 int = 200
var s2 int = 300
sum := calc.Add(s1,s2)
fmt.Printf("s1+s2=%d",sum) //500
fmt.Printf("caic.A=%d",caic.A) //200
fmt.Printf("caic.a=%d",caic.Test())
} //可以调用caic包中的Add函数和Test函数还有大写的的变量
四、匿名函数
//函数是一种类型,因此可以定义一个函数类型的变量
func add(a,b int) int{
return a + b
}
func testFunc1(){
f1:=add
fmt.Printf("type of f1 = %T
",f1) //打印变量用%T
sum := f1(2,5) //函数类型的变量
fmt.Printf("sum=%d
",sum)
}
func main(){
testFunc1()
}
//匿名函数,没有命名的函数
func testFunc2(){
f1 := func(a,b int) int{ //匿名函数
return a+b
}
fmt.Printf("type of f1=%T
",f1)
sum := f1(2,5)
fmt.Printf("sum = %d
",sum)
}
funt main(){
testFunc2()
}
//defer使用匿名函数
func testFunc3(){
defer func(){
fmt.Printf("defer i=%d
",i) //100
}()
i = 100
fmt.Printf("i=%d
",i)
}
//函数作为一个参数
func add(a,b int) int{
return a+b
}
func sub(a,b int) int{
return a-b
}
func calc(a,b int,op func(int,int)int)int{
return op(a,b)
}
func testDefer5(){
sum := calc(100,300,add)
sub := calc(100,300,sub)
fmt.Printf("sum-%d sub-%d
",sum,sub)
}
五、函数闭包
定义:一个函数和与其相关的引用环境组合而成的实体(匿名函数嵌套,闭包是外部函数嵌套内部函数,内部函数引用外部函数的变量,外部函数用完变量后,被内部函数引用并保留下来,作为自由变量使用,就是闭包)
func Adder() func(int) int{
var x int
return func(d int) int{
x += d
return x
}
}
func testClosure1(){
f:= Adder()
ret := f(1)
fmt.Printf("ret=%d
",ret) //1
ret = f(20)
fmt.Printf("ret%d
",ret) //21
ret = f(300)
fmt.Printf("ret=%d
",ret) //321
}
//test
func add(base int) func(int) int{
return func (i int) int{
base += i
return base
}
}
func testClosure1(){
tmp1 := add(10)
fmt.Println(tmp1(1),tmp1(2))
tmp2 := add(100)
fmt.println(tmp2(1),tmp2(2))
}
//test2
func test(suffix string) func(string) string{
return func(name string) string{
if !strings.HasSuffix(name,suffix){
return name + suffix
}
return name
}
}
func testClosure1(){
func1 := test(".bmp")
func2 := test(".jpg")
fmt.Println(func1("test")) //test.bmp
fmt.Println(func2("test")) //test.jpg
}
//test3
func calc(base int) (func(int) int,func(int) int) {
add := func(i int) int{
base += i
return base
}
return add,sub
}
func testClosure1(){
f1,f2 := calc(10)
fmt.Println(f1(1),f2(2)) //11 9
fmt.Println(f1(3), f2(4)) //12 8
fmt.Println(f1(5), f2(6)) //13 7
fmt.Println(f1(7), f2(8)) //14 6
}
//test4
func testClosure1(){
for i:=0;i<5;i++{
go func(){
Fmt.Println(i)
}()
}
time.Sleep(time.Second)
}
//输出 55555 有坑,每次i会赋值给函数中,但到5时才打印
//test5
func testClosure1(){
for i:=0;i<5;i++{
go func(index int) {
fmt.Println(index)
}(i)
}
time.Sleep(time.Second)
}
//输出 01234