golang 函数function解析 斐波拉契递归实现

本文通过一个斐波那契数列的递归实现,展示了Go语言中函数作为参数传递、错误处理(error接口、panic/recover)以及defer的用法。强调了函数是数据类型这一特性,允许函数作为参数传递,常用于构建通用逻辑或切面操作。同时,介绍了函数名首字母大小写的规则,以及如何限制结构体变量的直接赋值。
摘要由CSDN通过智能技术生成

关于斐波拉契,递归实现直接上代码,稍后对golang的func的特性做一些解释

package main

import (
	"errors"
	"fmt"
)

func main() {
	if err := logAndFun(fblq_sum, -10, "debug");err != nil{
		fmt.Println("运行程序异常奔溃,请检查日志",err.Error())
	}else{
		fmt.Println("切面函数未发现异常")
	}

}
// 函数: 为演示函数是可以作为参数传递的,并能执行
func logAndFun(f func(int) int, n int, leve string) error {
	var err error
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("程序异常", r)
			// 事实证明 defer 干预不了 返回结果
			err = errors.New("异常啦啦")
		}
	}()
	fmt.Println(leve, "执行形参函数执行 start")
	fmt.Println("函数类参数执行结果=", f(n))
	fmt.Println(leve, "执行形参函数执行 end")
	return err
}
// 函数: 求斐波拉契值
func fblq_sum(n int) int {
	if n >= 2 {
		return fblq_sum(n-1) + fblq_sum(n-2)
	} else if n>=0 {
		return 1
	}else{
		panic("能好好玩不,负数不可")
	}
}

运行结果:

debug 执行形参函数执行 start
程序异常 能好好玩不,负数不可
切面函数未发现异常

 

golang函数理解笔记

1.函数的异常使用 error接口管理的,可以通过errors包对异常做一些管理,同意使用接口的Error()方法输出异常字符串

2.panic是不可预知的运行时异常,如果不做捕获处理,会导致整个程序奔溃,不只是函数本身

3.recover()函数用于捕获panic异常,保障函数执行时异常,不会导致程序奔溃,如上示例代码有体现

4.defer 语句相当于java代码中的finally语句,即程序证明异常或panic都不会导致defer不执行,用于关闭IO资源、各种连接资源、持续崩溃前的预处理等等

5.defer语句中的匿名函数,虽然是最后才执行的,都是不能干预return中的变量赋值,如上代码执行结果有体现

6.两个特别重要的特征

        a. golang中函数是一种数据类型,也就是可以定义一个函数变量 var ff func(int,int) string

        b. 函数可以赋值给变量,可以作为函数的形参参数传递,只要符合指定的函数形参类型

// 函数作为参数传递 f
func logAndFun(f func(int) int, n int, leve string) error 
// 函数fblq_sum作为参数传递,前提满足logAndFun函数中对函数参数的定义 func(int) int
logAndFun(fblq_sum, -10, "debug")

 7. 针对上一段代码,可以理解为,函数logAndFun是为了执行一些既定的业务或切面逻辑,他的形参函数,是为了留一定的空间让你自定义各类执行逻辑,这点在定义数据库事物,及事物具体的执行逻辑由程序员自己根据业务去实现体现的尤为明显

8.函数、结构体、结构体内变量、方法、变量、接口、接口方法的大小写是有讲究的,大写代表可以跨package使用,否则只能本包内使用

9.利用如上特质。如果希望结构体(struct)内变量不可以随意赋值该怎么做呢?

        a.结构体大写,结构体中的变量小些。如此结构体可以被包外使用,但是变量无法随意赋值

        b.结构体变量的赋值,我们通过定义方法实现,当然必须大写,然后可以针对赋值的限制就可以写在函数里

type Car2 struct {
	title string
	name  string
}

func (c *Car2) SetTitle(title string) {
	if len(title) < 5 {
		return
	}
	c.title = title
}
func (c *Car2) SetName(name string) {
	if len(name) > 50 {
		c.name = name[:50]
	} else {
		c.name = name
	}
}

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值