go语言学习第三天==>函数、匿名函数与闭包、错误处理、defer关键字、painc()和recover()、type关键字

- go语言学习第三天==>函数、匿名函数与闭包、错误处理、defer关键字、painc()和recover()、type关键字

//
- 函数
func   函数名 (参数表)  (返回值表)/返回值  {函数体}
demo

func example1(x int) int {     
	if x == 0 {         
		return 5     
	} else{         
		return x     
	} 
}
//或者
func example2(x int) (int,int) {     
	if x == 0 {         
		return 1,2     
	} else{         
		return  2,2   
	} 
	return 2,22
}

函数调用
包名.函数名(参数表)
或者 同包可以不写
函数名(参数表)

example1(1)
//假设example2在包test中则
a,b:=test.example2(2)
//或者
test.example2(22222)

不定参数

func myfunc(args ...int) {     //接收不定数量的int类型参数
	for _, arg := range args {     
		fmt.Println(arg)     
	} 
}
//调用
myfunc()
myfunc(1)
myfunc(1,2)

不定参数传递

//假设有个myfunc2(args..int)
func myfunc(args ...int) { 

  // 按原样传递     
  myfunc3(args...) 
  // 传递片段,实际上任意的int slice都可以传进去     
  myfunc3(args[1:]...)   
} 

任意类型不定参数
用interface{}传递任意类型数据是Go语言的惯例用法。使用interface{}仍然是类型安全的

func Printf(format string, args ...interface{}) {  
	// ...  
} 

demo

package main 
 
import "fmt" 
 
func MyPrintf(args ...interface{}) {     
	for _, arg := range args {         
	switch arg.(type) {             
		case int:                   
			fmt.Println(arg, "is an int value.")             
		case string:                  
			fmt.Println(arg, "is a string value.")             
		case int64:                  
			fmt.Println(arg, "is an int64 value.")             
		default:                 
			fmt.Println(arg, "is an unknown type.")         
		}     
	} 
}
func main() {     
	var v1 int = 1     
	var v2 int64 = 234     
	var v3 string = "hello"     
	var v4 float32 = 1.234
	MyPrintf(v1, v2, v3,  v4) 
}

结果为:
1 is an int value.
234 is an int64 value.
hello is a string value.
1.234 is an unknown type.

多返回值

func (file *File) Read(b []byte) (n int, err Error)
//调用
n, _ := f.Read(buf)

//
匿名函数与闭包
1匿名函数 --即没有函数名

func(a, b int, z float64) bool {     
	return a*b <int(z)  
}

匿名函数可以直接赋值给一个变量

f := func(x, y int) int {     
	return x + y  
}

或者直接调用

func(a int) {     
		fmt.Println(a)
} (6666) // 花括号后直接跟参数列表表示函数调
//输出666

闭包
go的匿名函数就是一个闭包
闭包可以包含自由变量的代码块==》即函数外部变量

j:=10
a:=func(){
	j+=10 //使用了外部变量j
}
//结果j=20

价值:这些函数可以存储到变量中,作为参数传递,并且能动态创建和返回
demo 返回值为一个匿名函数的匿名函数

a := func()(func()) {         //匿名函数1
	var i int = 10         
	return func() {      //匿名函数2       
		fmt.Printf("i, j: %d, %d\n", i, j)         
	}     
}() //立即调用,返回匿名函数2给a
a() //执行a 即匿名函数2

//
错误处理
go语言引入了一个error接口来处理错误如下

type error interface {     
	Error() string 
}

如果函数要返回错误把error作为返回值的最后一个(一般情况)

func Foo(param int)(n int, err error) {     
// ...  
}
//调用
n, err := Foo(0)  
if err != nil {     
// 错误处理 
} else {     
// 使用返回值n  
} 

自定义error

type PathError struct {     
	Op   string 
	Path string     
	Err  error  //包装了一个error类型
}
func (e *PathError) Error() string {     
	return e.Op + " " + e.Path + ": " + e.Err.Error()   
}

//使用:直接把错误信息包装到PathError中
func Stat(name string) (fi FileInfo, err error) {    
	var stat syscall.Stat_t 
    err = syscall.Stat(name, &stat) 
    if err != nil {         
    	return nil, &PathError{"stat", name, err}     
    } 
    return fileInfoFromStat(&stat, name), nil 
} 

///
defer关键字
defer关键字==>延缓函数的执行
使用时在函数或者非法前加defer即可
遇到defer关键字 紧跟其后的函数会被延迟执行
直到包含该defer语句的函数执行完毕时,其后面的函数才会被执行
不论包含defer语句的函数是通过return正常结束,还是由于panic导致的异常结束。
一个函数中允许多个defer,执行顺序与声明顺序相反。
可用于打开、关闭、连接、断开连接、枷锁、释放资源
无论多复杂的的逻辑结构,资源都能被正确释放
释放资源的defer一般跟在请求资源的语句后

defer srcFile.Close()
defer dstFile.Close()
defer func() {     
	// 做你复杂的清理工作 
} ()

///
panic()和recover函数
go语言内置了这两个函数
func panic(interface{})
func recover() interface{}

当调用panic,正常的函数执行流程将立即终止

recover()函数用于处理错误终止

defer func() {     
	if r := recover(); r != nil {         
		log.Printf("Runtime error caught: %v", r)    
	}  
}()


type关键字
1定义结构体

type student struct{
	name string 
	id int
}

2 定义接口

type student interface{
	read()
	write()
}

3类型定义

type str string //以string为基础 定义一个str类型
type getStudent func(id int)//定义一个getStudent类型的方法

4类型别名

type str= string  //把string 取别名为str

类型查询
变量名.(type)

a:="im a boss"
v:=a.(type)
fmt.Println(v)
//结果为string
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值