1. 什么是函数
函数是一段可重用的代码块,用于执行特定的任务。它接受输入参数,执行一系列操作,并返回结果。函数能够提高代码的可读性、可维护性和可重用性。
2. 如何定义函数
函数的定义使用 func
关键字,基本语法如下:
func functionName(parameters) returnType {
return result
}
-
functionName
:函数名, 遵循标识符的命名规则,采用驼峰命名法 -
parameters
:可以包含零个或多个参数。用逗号分隔,每个参数由参数名和参数类型组成 。 -
returnType
:函数的返回类型,指定函数返回值的数据类型。 -
result
:函数的返回值,根据returnType
指定的类型来决定,多个返回值用括号括起来。
我们来看一个示例:
func add(a, b int) int {
return a + b
}
这个函数名为 add
,接受两个整数类型的参数 a
和 b
,并返回它们的和。
3. 传递函数参数类型
函数的参数可以是任意类型,包括基本类型和自定义类型。在函数调用时,可以传递参数的副本或指针。
需要注意的是,除了切片传递和指针传递,其它函数参数默认为值传递。
func updateValue(a int) {
a = 10
}
func updatePtr(a *int) {
*a = 20
}
func main() {
x := 5
updateValue(x)
// 输出:5
fmt.Println(x)
updatePtr(&x)
// 输出:20
fmt.Println(x)
}
在上面的示例中,虽然 x
被传递给了 updateValue
函数,但函数内部修改的只是参数 a
的副本,并不会影响到原始变量 x
。但updatePtr中,传递是指针地址,是对变量地址指向内容的修改,所以原始值也会变。
4. 函数返回值
函数可以有零个或多个返回值。可以通过在函数定义中指定返回类型来声明函数的返回值。
如果函数有多个返回值,则使用逗号分隔它们。
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("除数不能为零")
}
// golang中空用nil表示
return a / b, nil
}
在函数 divide
接受两个 float64
类型的参数,并返回商和错误信息。如果除数为零,则返回错误。
5. 函数的变量作用域
函数变量作用域分为全局作用域、函数作用域和语句块作用域三种。
-
全局作用域:在函数体外定义的变量具有全局作用域,可以在整个程序中访问。
-
函数作用域:在函数体内部定义的变量具有函数作用域,只能在函数内部访问。
-
语句块作用域:在
{}
块内定义的变量具有语句块作用域,只能在该块内访问。
var (
// 全局作用域在整个包内都起作用
counter int
// 第一个字母大写,其它包也可以直接调用,比如main.Intro
Intro string = "main包名称"
)
func sum(a int, b int) int {
counter++
return a + b
}
func echo() {
counter++
var linter = "下面输出结果集:"
fmt.Println(linter)
}
func main() {
echo()
fmt.Println("counter is ", counter)
// linter属于echo函数局部变量,所以在外部使用报错
// fmt.Println("localvar linter",linter)
if sum(1, 2) > 3 {
hint := "sum(1,2) value > 3"
fmt.Println(hint)
}
// 由于在代码块外部使用了,报错
// fmt.Println(hint)
}
6. 函数的递归调用
支持函数的递归调用,即函数可以直接或间接地调用自身。递归函数通常用于解决可以分解为较小规模相同问题的情况。
func factorial(n int) int {
if n == 0 {
return 1
}
return n * factorial(n-1)
}
上面的示例是一个计算阶乘的递归函数,它将 n
的阶乘计算为 n * (n-1)!
。
7. 函数的可变参数
定义接受可变数量参数的函数。在函数定义中,使用 ...
表示参数为可变参数。
func sum(numbers ...int) int {
result := 0
for _, num := range numbers {
result += num
}
return result
}
上面的示例中,函数 sum
接受可变数量的整数参数,并将它们求和后返回。
8. 函数的闭包使用
闭包是指一个函数与其相关的引用环境组合而成的实体,它来自函数体外部的变量引用。通过闭包,我们可以在一个函数内部访问其外部的变量。闭包可以用于实现一些高级的功能,例如实现缓存效果、实现函数式编程等
// add函数一个整数参数x,并返回一个函数,这个函数可以将传入的参数与x相加并返回结果。
func add(x int) func(y int) int {
count := 0
return func(y int) int {
count++
fmt.Println("闭包函数调用次数",count)
return x + y
}
}
func main() {
// 外部变量
fn := add(5)
fmt.Println(fn(3)) // 5 + 3 =8
fmt.Println(fn(7)) // 5 + 7 =12
}
// 输出内容
// 匿名函数调用次数 1
// 8
// 匿名函数调用次数 2
// 12
在上面的示例中,函数 add
返回了一个匿名函数,该匿名函数可以访问并修改 count
变量。并传递外部变量x=5,每次调用匿名函数时,count
的值都会增加,输出也是5+闭包传递的参数。
9. 函数的defer语句
-
defer即延迟语句,极个别的情况下,Go才使⽤defer、panic、recover这种异常处理形式。
-
defer可以延迟函数、延迟⽅法、延迟参数。
type Person struct {
Name string
}
// 结构体方法
func (p Person) getName() string {
fmt.Println("延迟方法getName")
return p.Name
}
func echo() {
fmt.Println("延迟函数执行")
}
func add(x int, y int) int {
fmt.Println("延迟参数", x, y)
return x + y
}
func main() {
p := Person{Name: "xiaoli"}
defer p.getName() // 延迟方法
defer echo() // 延迟函数
a := 7
b := 8
defer add(a, b) // 延迟参数
a = 10
b = 20
fmt.Println("正常执行的参数", a, b)
}
// 输出结果
// 正常执行的参数 10 20 程序执行到结尾
// 延迟参数 7 8 向上查找延迟执行,第一个找到add
// 延迟函数执行 继续向上查找延迟,找到echo()函数
// 延迟方法getName 最后找到方法p.getName
defer
语句会在函数返回前执行,即使发生了异常。
希望上面示例能够帮助你更好地理解和应用函数的概念。
原文始发于微信公众号(数据安全治理技术):golang基础07:什么是函数?函数的如何定义和使用?详细讲解golang函数
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论