持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
一、细节
- 函数的形参列表可以是多个,返回值列表也可以是多个。
- 形参列表和返回值列表的数据类型可以是值类型和引用类型。
- 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其它包文件使用,类似public , 首字母小写,只能被本包文件使用,其它包文件不能使用,类似private。
- 函数中的变量是局部的,
函数外不生效- 请看案例1 基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。- 请看案例2- 如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用
- 请看案例 3 - Go函数不支持重载。
- 在Go中,
函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用。- 请看案例 4 - 函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用!
--请查看 案例 5 - 为了简化数据类型定义,Go支持自定义数据类型,其基本语法为:
--请查看 案例 6
type 自定义数据类型名 数据类型 // 相当于别名
案例: type myInt int // myInt 等于 int使用
案例: type mySum func(int, int) int // mySum 等价于一个函数类型func(int, int)int
- 支持对函数返回值命名.
--请查看 案例 7
func
- 使用_标识符,忽略返回值。
--请查看 案例 7 - Go支持可变参数
--请查看 案例 8
// 支持0到多个参数
func sum(args... int) sun int{}
// 支持 1到多个参数
func sum(num1 int,args.... int) sum int{}
// args是 slice,通过args[index] 可以访问到各个值
// 如果一个函数的形参列表中有可变参数,则可变参数需要放在形参列表最后。
二、案例解析
2.1 案例1
在这个案例中,example()函数中的num1和main函数中的num1 并不是同一个,example()中的num1是其内部的局部变量
package main
import "fmt"
func example() {
var num1 int = 100
fmt.Println("num1 = ", num1)
}
func main() {
var num1 int = 10010
example()
fmt.Println("main num1 = ", num1)
}
2.2 案例2
函数内的num1不会影响到main中num1的值
package main
import (
"fmt"
)
func example2(num1 int) {
num1 += 10
fmt.Println("example num1 = ", num1)
}
func main() {
num1 := 100
example2(num1) // 输出 110
fmt.Println("main函数的num1 = ", num1) //输出100
}
2.3 案例3
先执行main中内容,首先会有一个num1 中的地址;调用example3(),其中example3()的形参 num1 是一个指针类型,此时将 main()函数中的 num1 的地址传递进去,其example3()的操作此时是使用的 main()函数中的 num1的地址进行操作
package main
import (
"fmt"
)
// num1 为 *int 类型
func example3(num1 *int) {
*num1 += 10
// *取值 &取地址
fmt.Println("example num1 = ", *num1)
}
func main() {
num1 := 100
example3(&num1) // 输出 110
fmt.Println("main函数的num1 = ", num1) //输出110
}
2.4 案例4
package main
import "fmt"
func getSum(num1 int, num2 int) int {
return num1 + num2
}
func main() {
a := getSum
r := a(10, 20)
// 输出 a的类型为: func(int, int) int, getSum()的类型:func(int, int) int
fmt.Printf("a的类型为: %T, getSum()的类型:%T\n", a, getSum)
// r的值为: 30
fmt.Printf("r的值为: %v", r)
}
2.5 案例5
函数既然是-种数据类型,因此在Go中,函数可以作为形参,并且调用
package main
import "fmt"
func getSum(num1 int, num2 int) int {
return num1 + num2
}
func myFunc(funvar func(int, int) int, num1 int, num2 int) int {
return funvar(num1, num2)
}
func main() {
result := myFunc(getSum, 100, 200)
fmt.Printf("result = %v", result)
}
2.6 案例6
package main
import "fmt"
func main() {
// 给int取别名, 在go中 myInt 和 int 是不同的数据类型
type myInt int
// 定义一个变量
var num1 myInt
// num1 = 0, type = main.myInt
fmt.Printf("num1 = %v, type = %T", num1, num1)
}
2.7 案例7
package main
import "fmt"
// 注意返回这里的命名,就不需要在函数中 := 声明
func getSum(num1 int, num2 int) (sum int, sub int) {
sum = num1 + num2
sub = num1 - num2
return
}
func main() {
n1 := 10
n2 := 20
// 理解 _ 的用意
sum, _ := getSum(n1, n2)
_, sub := getSum(n1, n2)
//sum = 30, sub=-10
fmt.Printf("sum = %v, sub=%v", sum, sub)
}
2.8 案例8
编写sum函数,求出1到多个int的和
package main
import "fmt"
func sum(num1 int, args ...int) int {
sum := num1
// 遍历 args
for i := 0; i < len(args); i++ {
sum += args[i]
}
return sum
}
func main() {
result := sum(100, 200, 300, 400)
// sum = 1000
fmt.Printf("sum = %v", result)
}
三、函数练习
3.1 判断代码是否正确,若正确输出什么内容
3.1.1 案例1
package main
import "fmt"
func sum(num1, num2 float32) float32 {
fmt.Printf("num1 Type : %T\n", num1)
return num1 + num2
}
func main() {
fmt.Println("sum = ", sum(10, 20))
//
// num1 Type : float32
// sum = 30
}
3.1.2 案例2
package main
import "fmt"
type mySum func(int, int) int
func sum(n1 int, n2 int) int {
return n1 + n2
}
func sum2(n1, n2, n3 int) int {
return n1 + n2
}
// 使用type自定义数据类型来简化定义
func myFunc(funcVar mySum, num1 int, num2 int) int {
return funcVar(num1, num2)
}
func main() {
a := sum
b := sum2
fmt.Println(myFunc(a, 10, 20))
// b这里 sum2 有3个形参接收,myFunc只有2个形参接收,类型不匹配
fmt.Println(myFunc(b, 100, 200))
}
3.3 请编写一个函数swap(n1 *int,n2 *int)可以交换n1和n2的值
// 编写一个函数swap(n1 int, n2 int)可以交换n1 n2的值
package main
import "fmt"
func swap(n1 *int, n2 *int) (int, int) {
*n1, *n2 = *n2, *n1
return *n1, *n2
}
func main() {
a := 10
b := 20
swap(&a, &b) // 传入a,b地址
fmt.Printf("a = %v, b = %v", a, b)
}