首页 > 其他分享 >golang函数

golang函数

时间:2024-02-20 17:46:31浏览次数:24  
标签:return 函数 int fmt golang func Println

函数定义

/*
函数定义关键字 func
func 函数名 (参数 参数类型) 函数返回值的类型
*/
func getInfo(name string, age int) string {
	return name
}

// 函数返回多个返回值:则返回类型括号包裹(返回值类型,类型..),即时返回两个int,也需要(int,int)
func getNum(x int, status bool) (int, bool) {
	return x, status

}

// 函数返回值命名:函数定义时给返回值命名,并在函数体内可以直接使用这些变量,最后通过return返回
// 返回值是int类型,给返回值命名为num,并且可以直接调用
func sumNumber(x, y int) (sum int) {
	sum = x + y
	return sum

}

// 函数参数简写:如果参数的类型一样,可以只写一个类型
func setName(name, nickname string, age, height int) string {
	return nickname
}

// 函数可变参数:可变参数是指函数的参数数量不固定,在参数名后加...来标识
func getParam(x ...int) []int {
	// 传递可变参数,传递的参数类型是一个切片
	return x
}



// 函数可以没有参数和返回值
func test(){
  	fmt.Println("t")

}

函数类型

可以使用type关键字来定义一个函数类型

/* 语法 */
//  类型的名字  该函数类型要传递的参数、该函数类型要返回的类型
type name func(string,string) string


// 自定义一个name类型
type name func(string, string) string

// 定义一个yoyo函数
func yoyo(a, b string) string {
	return a
}

func main() {
	// 定义一个test变量,是一个name类型
	var test name

	// 给test赋值的时候,因为上面声明了name类型,如果参数和返回值不符合name类型的条件,就会报错
	test = yoyo
	fmt.Printf("%T", test) // main.name  main文件里面的name类型

	// yoyo赋值给test,可以通过test()来当函数调用
	test("1", "1")

}


/*

也可以自定义其他类型,比如自定义一个myInt类型,需要是int
type myInt int

*/

函数当做参数传递和返回值

当参数传递:

/* 语法一 */

func a(num int) int {
	return num
}

func b(num int) int {
	return num
}

// 定义c方法,传递num参数,然后传递一个函数,这个函数是有一个int参数,返回也是int
func c(num int, f func(int) int) int {
	return f(num)
}

func main() {
	fmt.Println(c(1, a))
}

/* 语法二 */

// 自定义Number类型
type number func(int) int

// 定义c方法,传递num参数,然后传递一个函数,符合Number类型
func c(num int, f number) int {
	return f(num)
}

func main() {
	fmt.Println(c(1, a))
}

函数当做返回值:

/* 语法一 */
func b(num int) int {
	return num
}

// 自定义Number类型
type number func(int) int

// 定义c方法 返回类型是number
func c(num int) number {
	return b
}
/* 语法二 */

func b(num int) int {
	return num
}


// 定义c方法 指定返回值类型为 一个int参数且返回值值为int的函数
func c() func(int) int {
	return b
}

func main() {
	fmt.Println(c()(1))
}

匿名函数

匿名函数就是没有函数名的函数

func main() {

	// 匿名自执行函数,可以传递参数也可以不传
	func() {
		fmt.Println("test")
	}() // 在后面+()调用

	// 匿名函数赋值变量
	var fn = func(x int, y int) int {
		return x + y
	}
	// 调用匿名函数变量
	fn(1, 1)
}



函数递归

func A(n int) {
	fmt.Println("n")
	
	n--
	// n大于1的时候递归调用自身, 递归调用需要注意死循环问题
	if n > 1 {
		A(n)
	} 

}

函数闭包

image-20240220163253405

image-20240220163332001

// 写法:函数里面嵌套一个函数,最后返回里面的函数
func testA() func() int {
   i := 10
   return func() int {
   	i++
   	return i
   }

}

func main() {
   // testA 赋值给a  testA返回的是匿名函数
   var a = testA()
   // 调用a(),调用的是testA中的匿名函数   i常驻内存中,依次++
   fmt.Println(a()) // 11
   fmt.Println(a()) // 12
   fmt.Println(a()) // 13

}

defer语句

image-20240220164320350

	// 执行顺序 1、4、3、2
	fmt.Println(1)
	defer fmt.Println(2)
	defer fmt.Println(3)
	fmt.Println(4)
// eeee、aaa
func testA() {

	defer func() {
		fmt.Println("aaa")
	}()
	fmt.Println("eeee")
}

defer在命名返回值和匿名返回函数中的区别:

defer注册要延迟执行的函数时该函数所有的参数都要确定其他值,然后执行的时候按照执行顺序

image-20240220165432175

// 匿名返回值
func testA() int {
	var a int
	defer func() {
		a++

	}()
	return a
}
// 命名返回值
func testB() (b int) {
	defer func() {
		b++

	}()
	return b
}

func main() {
	fmt.Println(testA()) // 0
	fmt.Println(testB()) // 1
}

内置函数panic/recover

image-20240220170707925

panic的作用是主动抛出异常并终止程序执行

image-20240220171036425

  • recover()必须放在defer里面执行,recover的作用是监听panic抛出的异常,如果panic没有抛出异常,则是nil,可以以此来判断

  • recover()必须搭配 defer 使用。

  • defer 一定要在可能引发 panic 的语句之前定义

func testA() {
	fmt.Println("A")
	// 使用defer延迟执行
	defer func() {
		// recover 监听panic抛出的异常,如果!=nil,说明panic有抛出的异常,可以进行对应的处理,不终止程序执行
		err := recover()
		if err != nil {
			fmt.Println(err)
		}
	}()
  // 主动使用panic 抛出异常
	panic("抛出异常")

}

func testB() {
	fmt.Println("B")
}

func main() {
	testA()
	testB()
}

func sum(a, b int) int {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println(err) // runtime error: integer divide by zero

		}
	}()
	// 10 不能 / 0 ,所以会发生错误,go本身会使用panic抛出异常
	return a / b
}

func main() {
	fmt.Println(sum(10, 0))

}

搭配使用:

import (
	"errors"
	"fmt"
)

func name(n string) error {
	if n == "li"{
		return nil
	}	
	return errors.New("名字错误")
	

}

func main() {
	
	defer func() {
		// 3. 监听到抛出的异常
		err := recover()
		if err!=nil{
			fmt.Println("err")
			}
	}()
	//  1.调用name,如果返回nil 说明没有异常,不是nil则有异常
	nick := name("1")
	//  2. 如果有异常 则使用panic主动抛出
	if nick != nil{
		panic("error")
		}

}

标签:return,函数,int,fmt,golang,func,Println
From: https://www.cnblogs.com/Mickey-7/p/18023658

相关文章

  • Flink 增量窗口聚合函数 ReduceFunction(归约函数)和AggregateFunction(聚合函数)
    Flink增量窗口聚合函数定义了窗口分配器,只是知道了数据属于哪个窗口,可以将数据收集起来了;至于收集起来到底要做什么,其实还完全没有头绪。所以在窗口分配器之后,必须再接上一个定义窗口如何进行计算的操作,这就是所谓的“窗口函数”(windowfunctions)。经窗口分配器处理之后,数据可......
  • python不能跳转进入某个函数或模块的一种解决思路
    例如,下图中的get_bucket_mount_root函数可以顺利import进来,但是按ctrl键不能跳转进入这个函数: 一个解决思路是,在vscode终端中,打开python解释器,import上图中的hatbc库,然后用hatbc.__file__命令查找该库的__init__.py文件的路径,按住ctrl键,点击这个路径,即可跳转进入这个__init__.......
  • golang随机数源码分析及应用
    引言大家刚开始使用随机数的时候可能会这样写,但是他会产生一个问题,这是什么问题呢funcmain(){ fori:=0;i<10;i++{ rand.Seed(time.Now().Unix()) fmt.Println(rand.Intn(100)) }}发现打印出来的结果都是相同的让我们看看用代码分析为什么产生这个问题首......
  • 关于vue3的h函数
    h(ElInput,{class:'w200ml8',placeholder:'关键字搜索',clearable:true,modelValue:formData.url_pattern,'onUpdate:modelValue':(val:string)=&......
  • golang数组&切片&map
    数组数组声明funcmain(){ /*语法一*///数组名字[数组长度]数组类型 //声明一个数组长度为3类型是int会初始化为int类型的零值,默认值是[000] //声明数组的时候指定长度是一个常量,数组的不可改变,超出长度会报错 vararr[3]int //数组赋值 arr[0]=1......
  • C++函数用法
    1.getline函数的用法函数声明boolgetline(istream&in,string&s)功能说明从输入流读入一行到变量strings,即使是空格也可以读入。直到出现以下情况为止:读入了文件结束标志读到一个新行(有重载函数可以指定行分隔符,默认是"\n".)达到字符串的最大长度如果getline没有读......
  • 推荐系统中回归任务常用损失函数
    1.MSE(均方误差损失)优点:1.收敛快缺点:1.假设了样本服从正态分布,如果训练样本label不服从正态分布,则MSE并非最大似然估计2.对异常点很敏感 2.MAE(平均绝对误差损失)优点:不容易受异常值影响缺点:收敛速度慢,拟合能力弱 ......
  • java1.8LocalDate日期常用函数
    LocalDatenow=LocalDate.now();//获取当前日期2023-12-31Stringformat=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss"));//获取当前时间2023-12-3115:44:52intmonthValue=now.getMonthValue();//返回当前的月份intdayOfMonth=now.......
  • 备选数列 / 函数
    FibonacciSequenceFormula\[F_{1}=1\]\[F_{2}=1\]\[F_{i}=F_{i-1}+F_{i-2}(i\geq3)\]List\[F_1=1\]\[F_2=1\]\[F_{3}=2\]\[F_{4}=3\]\[F_{5}=5\]\[F_{6}=8\]\[F_{7}=13\]\[F_{8}=21\]\[F_{9}=34\]......
  • onMounted钩子函数场景
    onMounted是一个生命周期钩子,它在组件被挂载到DOM后被调用,这意味着,当组件被插入到页面中并且可以与DOM交互时,onMounted函数就会被执行在vue3中使用onMounted钩子才能获取页面DOM加载的元素信息,否则直接写在外面就会因为vue的异步特性导致数据而获取不到onMou......