Go语言基础之函数

1. golang函数特点:

复制代码
    • 无需声明原型。
    • 支持不定 变参。
    • 支持多返回值。
    • 支持命名返回参数。 
    • 支持匿名函数和闭包。
    • 函数也是一种类型,一个函数可以赋值给变量。

    • 不支持 嵌套 (nested) 一个包不能有两个名字一样的函数。
    • 不支持 重载 (overload) 
    • 不支持 默认参数 (default parameter)。

2. 函数定义

复制代码
func 函数名(参数)(返回值){
    函数体
}

其中:

  • 函数名:由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内,函数名也称不能重名(包的概念详见后文)。
  • 参数:参数由参数变量和参数变量的类型组成,多个参数之间使用,分隔。
  • 返回值:返回值由返回值变量和其变量类型组成,也可以只写返回值的类型,多个返回值必须用()包裹,并用,分隔。
  • 函数体:实现指定功能的代码块。

例如:

复制代码
func test(x, y int, s string) (int, string) {
    // 类型相同的相邻参数,参数类型可合并。 多返回值必须用括号。
    n := x + y          
    return n, fmt.Sprintf(s, n)
}

3.函数的调用

定义了函数之后,我们可以通过函数名()的方式调用函数。 例如我们调用上面定义的两个函数,代码如下:

复制代码
func main() {
	sayHello()
	ret := intSum(10, 20)
	fmt.Println(ret)
}

4.参数

4.1 类型简写

函数的参数中如果相邻变量的类型相同,则可以省略类型,例如:

复制代码
func intSum(x, y int) int {
	return x + y
}

上面x的类型就可以省略,因为和y的类型一样。

4.2 可变参数

可变参数是指函数的参数数量不固定。Go语言中的可变参数通过在参数名后加...来标识。

注意:可变参数通常要作为函数的最后一个参数。

复制代码
func intSum3(x int, y ...int) int {
	fmt.Println(x, y)
	sum := x
	for _, v := range y {
		sum = sum + v
	}
	return sum
}

调用上述函数:

复制代码
ret5 := intSum3(100)
ret6 := intSum3(100, 10)
ret7 := intSum3(100, 10, 20)
ret8 := intSum3(100, 10, 20, 30)
fmt.Println(ret5, ret6, ret7, ret8) //100 110 130 160

5.返回值

Go语言中通过return关键字向外输出返回值。

多返回值

Go语言中函数支持多返回值,函数如果有多个返回值时必须用()将所有返回值包裹起来。

举个例子:

复制代码
func calc(x, y int) (int, int) {
	sum := x + y
	sub := x - y
	return sum, sub
}

返回值命名

函数定义时可以给返回值命名,并在函数体中直接使用这些变量,最后通过return关键字返回。

例如:

复制代码
func calc(x, y int) (sum, sub int) {
	sum = x + y
	sub = x - y
	return
}

返回值补充

当我们的一个函数返回值类型为slice时,nil可以看做是一个有效的slice,没必要显示返回一个长度为0的切片。

复制代码
func someFunc(x string) []int {
	if x == "" {
		return nil // 没必要返回[]int{}
	}
	...
}

6.内置函数

内置函数 介绍
close 主要用来关闭channel
len 用来求长度,比如string、array、slice、map、channel
new 用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
make 用来分配内存,主要用来分配引用类型,比如chan、map、slice
append 用来追加元素到数组、slice中
panic和recover 用来做错误处理

panic/recover

Go语言中目前(Go1.12)是没有异常机制,但是使用panic/recover模式来处理错误。 panic可以在任何地方引发,但recover只有在defer调用的函数中有效。 首先来看一个例子:

复制代码
func funcA() {
	fmt.Println("func A")
}

func funcB() {
	panic("panic in B")
}

func funcC() {
	fmt.Println("func C")
}
func main() {
	funcA()
	funcB()
	funcC()
}

输出:

复制代码
func A
panic: panic in B

goroutine 1 [running]:
main.funcB(...)
        .../code/func/main.go:12
main.main()
        .../code/func/main.go:20 +0x98

程序运行期间funcB中引发了panic导致程序崩溃,异常退出了。这个时候我们就可以通过recover将程序恢复回来,继续往后执行。

复制代码
func funcA() {
	fmt.Println("func A")
}

func funcB() {
	defer func() {
		err := recover()
		//如果程序出出现了panic错误,可以通过recover恢复过来
		if err != nil {
			fmt.Println("recover in B")
		}
	}()
	panic("panic in B")
}

func funcC() {
	fmt.Println("func C")
}
func main() {
	funcA()
	funcB()
	funcC()
}

注意:

  1. recover()必须搭配defer使用。
  2. defer一定要在可能引发panic的语句之前定义。

参考文章:

https://www.fansimao.com/1006273.html

https://www.fansimao.com/1006288.html

https://www.fansimao.com/1006299.html

相关推荐
uhakadotcom1 分钟前
Ruff:Python 代码分析工具的新选择
后端·面试·github
uhakadotcom4 分钟前
Mypy入门:Python静态类型检查工具
后端·面试·github
喵个咪9 分钟前
开箱即用的GO后台管理系统 Kratos Admin - 定时任务
后端·微服务·消息队列
Asthenia041212 分钟前
ArrayList与LinkedList源码分析及面试应对策略
后端
桃子酱紫君24 分钟前
华为配置篇-BGP实验
开发语言·华为·php
QTX1873036 分钟前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
shaoing40 分钟前
MySQL 错误 报错:Table ‘performance_schema.session_variables’ Doesn’t Exist
java·开发语言·数据库
Asthenia041241 分钟前
由浅入深解析Redis事务机制及其业务应用-电商场景解决超卖
后端
Asthenia041242 分钟前
Redis详解:从内存一致性到持久化策略的思维链条
后端
Asthenia041242 分钟前
深入剖析 Redis 持久化:RDB 与 AOF 的全景解析
后端