//函数
//函数是一段代码的封装
//Go语言函数传递的参数全部是形式参数
//Go语言中函数的return不是原子操作,在底层是分为两步来执行
//第一步:返回值赋值
//第二步:真正的RET返回
//函数中如果有defer,那么defer执行的时机是在第一步和第二步之间
//函数中查找变量的顺序
//1.先在函数内部查找
//2.找不到就往函数的外面查找,一直找到全局
//函数的声明
//func 函数名(参数)(返回值){
//函数体
//}
//有参数有返回值
func sum(x int,y int)(ret int){
ret=x+y
return //可以不用在return后面加值
}
//没有参数有返回值
func f3()int{
return 2
}
//没有参数没有返回值
func f2(){
fmt.Println("f2")
}
//多个返回值
func f5()(int,string){
return 1,"沙河"
}
//参数的类型简写
func f6(x,y int,z,m,n string)int{
return x+y
}
//可变长参数
func f7(x string,y ....int){
fmt.Println(x)
fmt.Println(y) //slice切片
}
func deferDemo(){
fmt.Println("start")
defer fmt.Println("嘿嘿嘿")//defer把它后面的语句延迟到函数即将返回的时候再执行
defer fmt.Println("哈哈哈")
defer fmt.Println("呵呵呵")
fmt.Println("end")
//打印顺序,呵呵呵,哈哈哈,嘿嘿嘿
}
func defe(){
x:=5
defer func(){
x++
}()
return x
}//返回5
func defe2()(x int){
defer func(){
x++
}()
return 5
} //返回值=x为6
//函数类型
func f1(){
fmt.Println("Hello 沙河")
}
func main(){
a:=f1
fmt.Printf("%T\n",a)//a是涵数类型
}
func f2()int{
return 10
}
func f3(x func()int) //有返回值类型函数做参数
func f3(x func()) //无返回值类型函数做参数
func f4(x func())func(int,int)int //返回值也是函数类型
//匿名函数
//函数内部不能定义带名字的函数
func main(){
f1:=func(x,y int){
fmt.Println(x+y)
}
f1(10,20)
func(){
fmt.Println("Hello world!")
}
func(){
fmt.Println(x+y)
}(100,200)//只调一次,可立即执行
}
func lixiang(x int){
tmp:=func(){
fmt.Println(x)
}
tmp()
}
//闭包
//一个函数除了引用给的参数之外,还用到了外部作用域的变量
//底层原理:
//1.函数可以作为返回值
//2。函数内部查找变量的顺序,先在自己内部找,找不到外层找
func lixiang2(x func(int,int),m,n int){
tmp:=func(){
x(m,n)//x()和m、n都来自外部
}
tmp()
}
//例题1
func makeSuffixFunc(suffix string) func(string)string{
return func(name string)string{
if !string.HasSuffix(name,suffix){ //判断suffix是否为name的后缀
return name+suffix
}
return name
}
}
func main(){
jpgFunc:=makeSuffixFunc(".jpg")
txtFunc:=makeSuffixFunc(".txt")
fmt.Println(jpgFunc("test"))
fmt.Println(jpgFunc("呵呵.jpg"))
fmt.Println(txtFunc("test"))
fmt.Println(jpgFunc("呵呵.txt"))
}
//例题2
func calc(base int)(func(int) int,func(int) int){
add:=func(i int)int{
base+=i
return base
}
sub:=func(i int)int{
base-=i
return base
}
return add,sub
}
func main(){
f1,f2:=calc(10)
fmt.Println(f1(1),f2(2))
}
//defer例题
func calc(index string,a,b int)int{
ret:=a+b
fmt.Println(index,a,b,ret)
return ret
}
func main(){
a:=1
b:=2
defer calc("1",a,calc("10",a,b))
a=0
defer calc("2",a,calc("20",a,b))
b=1
}
//执行顺序:
//1.defer calc("1",a,calc("10",a,b)) 延迟执行,calc("10",a,b)先执行
//2.calc("10",a,b) 即calc("10",1,2)
//3.defer calc("1",a,3)
//4.a=0
//5.defer calc("2",a,calc("20",a,b))
//6.calc("20",a,b) 即calc("20",0,2)
//7.defer calc("2",a,2)
//8.b=1
//9.calc("2",0,2)
//10.calc("1",0,3)
//异常恢复
func funcA(){
fmt.Println("A")
}
func funcB(){
defer func(){ //异常退出时会执行defer函数
err:=recover() //recover尝试恢复错误,返回错误类型
fmt.Println(err)
fmt.Println("释放数据库连接...")
}()
panic("出现了严重的错误!!!") //抛出系统崩溃错误退出
fmt.Println("B")
}
func funcC(){
fmt.Println("C")
}
func main(){
funcA()
funcB()
funcC()//没有recover不会执行该语句,有的话会执行
}
//输入
func main(){
fmt.Scanf("%s %d %s\n",&name,&age,&class)
fmt.Scanln(&name,&age,&class)
fmt.Scan(&name,&age,&class)
}
//作业:分金币
package main
import (
"fmt"
)
var (
coins = 50
user = []string{
"Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth",
}
distribution = make(map[string]int, len(user))
)
func dispatchCoin() (coin int) {
for _, cur_user := range user {
for _, i := range cur_user {
switch i {
case 'e', 'E':
distribution[cur_user]++
coins--
case 'i', 'I':
distribution[cur_user] += 2
coins -= 2
case 'o', 'O':
distribution[cur_user] += 3
coins -= 3
case 'u', 'U':
distribution[cur_user] += 4
coins -= 4
}
}
}
return coins
}
func main() {
left := dispatchCoin()
fmt.Println("剩下:", left)
}