读书笔记之Go函数

本文介绍了Go语言中函数的声明与调用,包括参数传递规则,如小内存数据类型使用非指针,大内存数据类型使用指针。详细阐述了函数变量、匿名函数、闭包、可变参数、类型判断、延迟执行、错误处理和 panic/recover 机制。重点讲解了函数作为变量、数据类型以及在接口实现中的应用,展示了Go语言在函数处理上的灵活性和高效性。
摘要由CSDN通过智能技术生成
  1. 小内存数据类型适用:非指针+返回值 !【传递速度更快,这也就是math中函数更喜欢非指针参数】
  2. 大内存数据类型适用:指针!【结构体】

声明函数

func 函数名(参数列表) (返回参数列表){
	...
}

参数列表: 相同类型相邻参数,可以只保留最后一个类型:

func add(a,b int) int{
	return a+b
}

返回参数列表: 【要么全使用非命名,要么全使用命名!】

func RetVlaues() (int ,int){
	return 1,2
}

或可以命名后直接在函数中使用:

func RetVlaues() (a,b int){
	a = 1
	b = 2
	return
}

调用函数

返回值变量列表 := 函数名(参数列表)

参数传递效果

  1. 数组等基本数据类型,直接会拷贝一份数据传入!如果需要原地修改,则使用 &变量名 传入数据地址让其进行操作!
  2. 派生数据类型则本身会拷贝地址集合传入,让函数进行原地修改!但如果地址集合会被函数修改,则需要函数返回新的地址集合进行刷新! (大多数都需要return地址集合)

函数变量:把函数作为值保存到变量中

f 被成为回调函数!!!

	var f func() //回调函数
	
	var ff func() bool
	
	func main(){
		f = f1
		f() //执行函数
	
		ff = f2
		f2() //执行函数
	}
	
	func f1() {
		fmt.Println("f1被执行")
	}
	
	func f2() bool {
		fmt.Println("f2被执行")
		return true
	}

用途:链式处理:其实就是将对数据的操作函数放入一个切片集合中,for range切片执行每个函数!

var chain []func(T) T
chain中添加func!

for _,proc := chain {
	result = proc(result)
}

匿名函数

没有名字的函数,常用于实现回调函数、闭包【访问外部变量的匿名函数!!!】等!

声明

func(参数列表) (返回参数列表){
	...
}

实例

  1. 函数赋给变量,使用变量调用:
var f = func() bool{
	return true
}

f()
  1. 直接构建调用:【后面的 (100) 就是函数调用并传入参数啊!】
func(a int) {
		fmt.Println(a)
}(100)

函数类型实现接口:把函数作为接口来调用 (😵)

使用情况:
一、前提:有一个接口,只有一个方法:

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

二、目的:想实现这个接口的这个函数,成为接口的实现体!但是,又不想每次实现一个都需要:一个新struct 、然后该struct是实现该接口(函数)!
三、方法:将目标函数ServeHTTP创建成一种数据类型HandlerFunc,该数据类型实现目标接口的方法!

这里的type和var是两种概念

  1. var HandlerFunc func(ResponseWriter,*Request):是声明了一个func(ResponseWriter,*Request)类型的函数变量HandlerFunc
  2. type HandlerFunc func(ResponseWriter, *Request):是声明了一种func(ResponseWriter, *Request)的数据类型HandlerFunc(eg:type myInt int64)
type HandlerFunc func(ResponseWriter, *Request) /这是一种数据类型(类别成structfunc (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { /这是这种数据类型所拥有的函数(类比成struct的方法)
	f(w, r)
}

四、实现:这样就可以发生一个神奇的事情:HandlerFunc(一个函数) 就可以返回一个Handler接口类型的实例,且传入的函数就是我们实现接口的函数!

// dest(w ResponseWriter, r *Request)是我们想要实现的ServeHTTP(ResponseWriter, *Request)‘
var s = HandlerFunc(dest) /将dest转换为HandlerFunc(哈哈哈没想到吧!)
那么s就是我们需要每次都构建的struct了
因为s现在是HandlerFunc类型,并且他实现了Handler

思想:任何type可以实现interface!!!

闭包(Closure):引用了外部变量的匿名函数

a := 0
闭包 := func(b int) int {
	a++
	return a+b
}

闭包(使用外部变量的匿名函数,不需要参数传进来),并不会拷贝外部变量,会直接修改外部变量的值! 所以它才表现出记忆能力!

可变参数

可变参数必须在参数列表中的最后:【可变参数在函数中被看作一个切片使用!

func 函数名(固定参数列表,v... T)(返回参数列表){
	...
}

判断参数类型

switch v.(type)

func TypeValue(v interface{})  {
	switch v.(type) {
	case int:
		fmt.Println("类型为:int")
	case bool:
		fmt.Println("类型为:bool")
	...
	}
}

延迟执行语句defer

  1. 多个defer语句会放入延迟调用
  2. return 语句后开始从栈中pop执行语句
  3. 目的: 释放锁、释放文件句柄

Go中的错误error

error 为一个错误接口

type error interface {
	Error() string
}

errors创建error

var err = errors.New("发生错误")

自定义error

func main() {
	err = NewMyError(404,"找不到")
	if err != nil {
		log.Fatal(err)
	}
}

// 1.声明错误结构
type myError struct {
	code int
	message string
}

// 2.实现error接口方法,返回错误描述
func (e *myError) Error() string{
	return fmt.Sprintf("code:%d message:%s",e.code,e.message)
}

// 3.NewMyError 构造自定义错误并返回
func NewMyError(code int, message string) error {
	return &myError{code: code,message: message}
}

宕机(panic):程序终止运行

  1. 直接调用内建函数:(注意可以传入任何参数)
func panic(v interface{})
  1. 由程序Runtime层抛出的panic崩溃

宕机恢复(recover):防止程序崩溃

如果panic类似于抛出异常,那么recover就相当于try catch

panic()recover()模板:
(1)recover()必须在defer中!
(2)panic() 不会调用本函数中的defer,所以panic()recover() 必须在两个函数中运行,当然panic()先运行!

// recover函数
func ProtectFunc(entry func()) {
	defer func() {
		// 获取宕机异常
		err := recover()
		if err == nil {
			return
		}
		switch err.(type) {
		case runtime.Error:
			fmt.Println("出现运行时宕机:",err)
		default:
			fmt.Println("手动宕机:",err)
			
		}
	}()
	entry()
}

拓展

函数可以是一种变量,也可以是一种数据类型!

var  HandlerFunc func(ResponseWriter,*Request) //是声明了一个func(ResponseWriter,*Request)类型的函数`变量HandlerFunc`
type HandlerFunc func(ResponseWriter, *Request) //是声明了一种func(ResponseWriter, *Request)的`数据类型HandlerFunc`(eg:type myInt int64)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值