关于斐波拉契,递归实现直接上代码,稍后对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
}
}