1、函数的基本规则
package main
import "fmt"
func main() {
/*
1.C语言是由函数组成的
2.Go语言也是由函数组成的
3.C语言函数的格式
返回值类型 函数名称(形参列表){
被控制的语句;
}
4.Go语言函数的格式
func 函数名称(形参列表)(返回值列表){
被控制的语句;
}
5.C语言函数的类型
5.1没有返回值没有形参的函数
5.2有返回值没有形参的函数
5.3没有返回值有形参的函数
5.4有返回值有形参的函数
6.Go语言函数的类型和C语言一样
注意点:
1.在C语言中如果函数的定义写在函数的调用之前必须先声明再调用
在Go语言中如果函数的定义写在函数的调用之前, 不用声明就可以调用, Go语言没有声明
2.Go语言中如果函数只有一个返回值, 那么返回值列表的()可以省略
3.Go语言中如果有返回值, 可以在返回值列表中定义变量, 然后在函数体中直接使用
4.如果在返回值列表中定义了变量, 那么return后面可以不用写任何内容, 默认就会将返回值列表中定义的变量返回
5.Go语言中一个函数可以有多个返回值
6.如果一个函数有多个返回值, 但是我们只想使用其中的一个, 那么可以在接收的时候使用_来忽略, 不需要的那个返回值
7.因为_在Go语言中有特殊的含义, 所以在定义标识符的时候_不能单独作为标识符
8.如果返回值列表中有多个返回值, 并且连续的多个返回值的数据类型都一样, 那么只用在最后一个变量后面添加数据类型即可
9.如果形参列表中有多个形参, 并且连续的多个形参的数据类型都一样, 那么只用在最后一个变量后面添加数据类型即可
*/
//say()
//res := getNumber()
//fmt.Println(res)
//a, b := getValue()
//fmt.Println("a = ", a, "b = ", b)
//a, _ := getValue()
//fmt.Println("a = ", a)
//sum(10, 20)
res := minus(10, 20)
fmt.Println(res)
}
// 1.没有返回值没有形参的函数
func say(){
fmt.Println("没有返回值没有形参")
}
// 2.有返回值没有形参的函数
// 2.1只有一个返回值的函数
//func getNumber()(int){
//func getNumber()int{
// return 888
//}
func getNumber() (num int){
num = 999
return
}
// 2.2有多个返回值的函数
//func getValue() (int, int){
// return 666, 888
//}
//func getValue() (num int,value int){
func getValue() (num ,value int){
//num = 666
//value = 888
//return
return 666, 888
}
//func test()(num int, temp float64, value int){
//func test()(num , value int, temp float64){
//
//}
// 3.没有返回值有形参的函数
//func sum(a int, b int){
func sum(a , b int){
res := a + b
fmt.Println(res)
}
// 4.有返回值有形参的函数
//func minus(a, b int)(res int){
// res = a - b
// return
//}
func minus(a int, b int)(int){
res := a - b
return res
}
2、函数的参数
package main
import "fmt"
func main() {
/*
1.在C语言中如果基本数据类型作为函数的参数, 是值传递, 在函数内修改形参不会影响到外界的实参
2.Go语言和C语言一样/ int float bool
3.如果想在函数内部修改外界传入的实参, 那么必须传入指针
*/
num := 666
fmt.Println(num)
//change1(num)
change2(&num)
fmt.Println(num)
}
func change1(a int) {
a = 789
}
func change2(a *int) {
*a = 789
}
3、什么是匿名函数
package main
import "fmt"
func main() {
/*
1.什么是匿名函数?
普通的函数都是有名字的函数, 而匿名函数就是没有名字的函数
2.匿名函数的应用场景:
一般情况下某个函数只会被调用一次, 我们就会使用匿名函数
作为函数的参数, 或者作为函数的返回值
3.注意点:
3.1匿名函数定义之后, 如果没有立即调用, 编译器会报错
3.2也可以将一个匿名函数保存到一个变量中
在C语言中我们知道, 我们可以定义一个指向函数的指针来保存函数的地址, 然后通过指针来调用函数
在Go语言中函数是一等公民(可以定义变量, 作为形参, 作为返回值), 所以在Go语言中也可以用函数类型来定义变量(相当于C语言中指向函数的指针)
3.3由于函数是一等公民, 所以以前定义变量所有的格式, 都可以用于定义函数类型的变量
var 变量名称 函数类型
var 变量名称 函数类型 = 匿名函数
var 变量名称 = 匿名函数
变量名称 := 匿名函数
var(
var 变量名称 = 匿名函数
)
C语言中指向函数的指针
int test(int a, int b){}
int (*test)(int, int)
*/
// test相当于找到函数的定义, 然后调用函数
test()
// 直接定义一个函数, 然后立即调用这个函数
//func(){
// fmt.Println("匿名函数")
//}()
// 定义一个函数类型的变量, 保存匿名函数, 然后通过函数类型的变量调用匿名函数
//f := func() {
// fmt.Println("匿名函数")
//}
var f func() = func() {
fmt.Println("匿名函数")
}
//fmt.Printf("%T\n", f)
f()
}
func test(){
fmt.Println("test")
}
4、匿名函数的应用
4.1
package main
import "fmt"
func main() {
/*
1.作为其他函数的参数
2.作为其他函数的返回值
*/
/*
res1 := sum(10, 20)
res2 := minus(10, 20)
fmt.Println(res1)
fmt.Println(res2)
*/
// 需求: 定义一个匿名函数, 实现两个数相加
//fn := func(a, b int) int {
// return a + b
//}
//fmt.Printf("%T\n", fn)
//相当于如下:
//var fn func(int, int) int = func(a, b int) int {
// return a + b
//}
//res := fn(10, 20)
//fmt.Println(res)
//var method func(int, int) int = fn
//res := method(10, 20)
//fmt.Println(res)
//匿名函数的赋值 和 变量的使用 类比如下
//var num int = 6
//var value int = num
//fmt.Println(value)
//result := calculate(10, 20, fn)
result := calculate(10, 20, func(a, b int) int {
return a + b
})
fmt.Println(result)
}
func calculate(a, b int, method func(int, int) int) (int) {
res := method(a, b)
return res
}
func sum(a, b int) int {
return a + b
}
func minus(a, b int) int {
return a - b
}
4.2
package main
import "fmt"
func main() {
// 1.匿名函数作为函数的参数
/*
//var fn func()
//fn = func() {
// fmt.Println("匿名函数")
//}
//fmt.Printf("%p\n", fn)
//test(fn)
test(func() {
fmt.Println("匿名函数")
})
*/
/*
var fn func()
fn = test()
fn()
*/
//2.作为其他函数的返回值
var fn func(int, int)int
fn = test()
res := fn(10, 20)
fmt.Println(res)
}
func test()func(int, int)int{
return func(a int, b int)int {
return a + b
}
}
//func test() func() {
// return func() {
// fmt.Println("匿名函数")
// }
//}
//func test(method func()) {
// fmt.Printf("%p\n", method)
// method()
//}
4.3、
package main
import (
"fmt"
)
func main() {
//work(func() {
// fmt.Println("参与部门会议")
// fmt.Println("修改BUG")
// fmt.Println("完成老大安排的任务")
// fmt.Println("... ...")
// fmt.Println("提交代码")
//})
work(func() {
fmt.Println("组织部门会议")
fmt.Println("给部门的员工分配任务")
fmt.Println("检查部门员工昨天提交的代码")
fmt.Println("... ...")
})
}
// 攻城狮的一天
func work(method func()){
// 1.上班前
func(){
fmt.Println("起床")
fmt.Println("刷牙洗脸")
fmt.Println("吃早餐")
fmt.Println("做地铁")
fmt.Println("打卡")
fmt.Println("打开电脑")
}()
// 2.上班中
method()
// 3.下班之后
func(){
fmt.Println("关电脑")
fmt.Println("打卡")
fmt.Println("坐地铁")
fmt.Println("到家")
fmt.Println("吃饭")
fmt.Println("娱乐")
fmt.Println("刷牙洗脸")
fmt.Println("睡觉")
}()
}
// 项目经理的一天
func work2(){
fmt.Println("起床")
fmt.Println("刷牙洗脸")
fmt.Println("吃早餐")
fmt.Println("做地铁")
fmt.Println("打卡")
fmt.Println("打开电脑")
fmt.Println("组织部门会议")
fmt.Println("给部门的员工分配任务")
fmt.Println("检查部门员工昨天提交的代码")
fmt.Println("... ...")
fmt.Println("关电脑")
fmt.Println("打卡")
fmt.Println("坐地铁")
fmt.Println("到家")
fmt.Println("吃饭")
fmt.Println("娱乐")
fmt.Println("刷牙洗脸")
fmt.Println("睡觉")
}
// 程序员的一天
func work1() {
fmt.Println("起床")
fmt.Println("刷牙洗脸")
fmt.Println("吃早餐")
fmt.Println("做地铁")
fmt.Println("打卡")
fmt.Println("打开电脑")
fmt.Println("参与部门会议")
fmt.Println("修改BUG")
fmt.Println("完成老大安排的任务")
fmt.Println("... ...")
fmt.Println("提交代码")
fmt.Println("关电脑")
fmt.Println("打卡")
fmt.Println("坐地铁")
fmt.Println("到家")
fmt.Println("吃饭")
fmt.Println("娱乐")
fmt.Println("刷牙洗脸")
fmt.Println("睡觉")
}
5 闭包
package main
import "fmt"
func main() {
/*
1.什么是闭包?
闭包就是一个特殊的匿名函数
只要匿名函数中用到了外界的变量, 那么我们就把匿名函数叫做闭包
注意点:
只要闭包还在使用外界的变量, 那么外界的变量就会一直存在
*/
/*
num := 10 // 11 12
a := func() {
num++
fmt.Println(num)
}
a() // 11
a() // 12
a() // 13
*/
// addUpper会返回一个闭包, 那么fn中保存的就是这个闭包, 那么fn就等于闭包
// 所以按照Go语言的规则, 只要fn还在, addUpper中被闭包引用的变量就不会释放
fn := addUpper()
fn()
fn()
fn()
}
func addUpper() func() {
x := 1
return func() {
x++
fmt.Println(x) // 2 , 3 , 4
}
}
网友评论