go(四)

go(四)

前四篇go基础笔记大部分cv–只因–的,主要本人是懒得写了,后面会继续更新go的基础及其框架,预计今年年底更完吧(感谢狂神_)

一、什么是函数

img

func main() {
	//调用函数 函数名()
	fmt.Println(add(1, 2)) //3
}

func add(a, b int) int {
	c := a + b
	return c
}

二、函数的声明

func main() {
	printinfo()

	myprint("haha")

	fmt.Println(add2(1, 2))

	swap(1, 2)
	
}

// 无参返回值函数
func printinfo() {
	fmt.Println("printinfo")
}

// 有一个参数的函数
func myprint(msg string) {
	fmt.Println(msg)
}

// 有两个参数的函数
// 有一个返回值的函数
func add2(a, b int) int {
	c := a + b
	return c
}

// 有多个返回值的函数
func swap(a, b int) (int, int) {
	return b, a
}

三、形式参数和实际参数

// max 两个数字比大小
// 形式参数:定义函数时,用来接收外部传入数据的参数,就是形式参数
// 实际参数:调用函数时,传给形参的实际数据叫做实际参数
func max(num1, num2 int) int {
	var result int
	if num1 > num2 {
		result = num1
	} else {
		result = num2
	}

	//一个函数定义上有返回值,那么函数中必须使用return语句
	//返回值
	//调用处需要使用变量接受该结果
	return result
}

四、可变参数

概念:一个函数的参数类型确定,但是个数不确定,就可以使用可变参数

func myfunc(arg ... int){}

//arg ... int 告诉go这个函数接收不定数量的参数,类型全部都是int
func main() {
	getSum(1, 2, 3, 4, 5, 6, 7, 100)
}

func getSum(nums ...int) {
	sum := 0

	for i := 0; i < len(nums); i++ {
		fmt.Println(nums[i])
		sum += nums[i]
	}
	fmt.Println("sum:", sum)

}

在这里插入图片描述

五、值传递和引用传递

在这里插入图片描述

值传递

func main() {

	//定义一个数组
	arr1 := [4]int{1, 2, 3, 4}
	fmt.Println("arr1默认数据", arr1)
	update(arr1)
	fmt.Print("arr1调用函数后数据", arr1)
	//arr2的数据是从arr1复制来的,所以是不同的空间
	//修改arr2并不会影响arr1
	//值传递:传递的是数据的副本,修改数据,对于原始的数据没有影响
	//值类型的数据,默认都是值传递,基础类型 array struct
}

func update(arr2 [4]int) {
	fmt.Println("arr2接收数据", arr2)
	arr2[0] = 10
	fmt.Println("arr2修改后数据", arr2)
}

在这里插入图片描述

在内存中:

在这里插入图片描述

值传递类型的改变的都是原先数据的副本,两份分别在不同的内存空间中!,所以修改 arr1 , arr2 不会改变!

引用传递

// 引用传递
func main() {

	//切片,可以扩容的数组
	s1 := []int{1, 2, 3, 4}
	fmt.Println("s1默认数据", s1)
	update2(s1)
	fmt.Print("s1调用函数后数据", s1)
}

func update2(s2 []int) {
	fmt.Println("s2接收数据", s2)
	s2[0] = 10
	fmt.Println("s2修改后数据", s2)

}

在这里插入图片描述

在内存中:

在这里插入图片描述

s1 和 s2两个引用 都对同一片内存空间进行操作,改变s1 ,s2 当然也会变!

六、函数变量的作用域

在这里插入图片描述

//全局变量
var num int = 100
func main() {
	
	//函数体内的局部变量
	temp := 100
	if b := 1 ; b<=10{
		temp := 50
		fmt.Println(temp)//局部变量,就近原则
		fmt.Println(b)
	}
	fmt.Println(temp)
	fmt.Println(num)
}

func f1()  {
	a := 1
	fmt.Println(a)
	fmt.Println(num)
}

func f2()  {
	b := 2
	fmt.Println(b)
	fmt.Println(num)
}

七、递归函数

在这里插入图片描述

package main

import "fmt"

func main() {
	//递归(十分消耗内存)
	//自己调用自己
	sum := getSum(5)
	fmt.Println(sum)

}

// 5
// getSum(4) + 5
// getSum(3) + 4
// getSum(2) + 3
// getSum(1) + 2
// 1
func getSum(n int) int {

	//当n=1满足条件时,此时main函数的局部变量(sum)已经累加成5+4+3+2+1 = 15
	//这里的if相当于暂停条件
	if n == 1 {
		return 1
	}

	return getSum(n-1) + n //只有当 n 满足上面的if条件才会停止调用自己
}

八、defer

在这里插入图片描述

func main() {
	f("1")
	fmt.Println("2")
	defer f("3")
	fmt.Println("4")    //1 2 4 3
}

func f(s string) {
	fmt.Println(s)
}

在这里插入图片描述

func main() {
	f("1")
	fmt.Println("2")
	defer f("3")
	fmt.Println("4")
	defer f("5")
	fmt.Println("6")
	defer f("7")
	fmt.Println("8")   //1 2 4 6 8 7 5 3
}

func f(s string) {
	fmt.Println(s)
}
func main() {
	a := 10
	fmt.Println("a=", a)
	//参数已经传递过去了 在最后执行
	defer f(a)
	a++
	fmt.Println("end a=", a)
}

func f(s int) {
	fmt.Println("函数里面的a=", s)
}

九、函数的本质

// func() 本身就是一个数据类型
func main() {

	//f3 如果不加括号 函数就是个变量
	//f3() 如果加了括号那就成了函数的调用
	fmt.Printf("%T\n", f3) //func(int, int)

	//定义函数类型的变量
	var f5 func(int, int)
	f5 = f3   //引用类型的
	f5(1, 2)
}

func f3(a, b int) {
	fmt.Println(a, b)
}

在这里插入图片描述

十、匿名函数

// 匿名函数
func main() {
	h1()
	h2 := h1 //函数本身也是一个变量
	h2()

	//匿名函数
	h3 := func() {
		fmt.Println("我是h3函数")
	}
	h3()

	x1 := func(a, b int) int {
		fmt.Println(a, b)
		return a + b
		//fmt.Println("我是h4函数")
	}(1, 2)

	fmt.Println(x1)
}

func h1() {
	fmt.Println("我是h1函数")
}

在这里插入图片描述

十一、函数式编程

在这里插入图片描述

func main() {

	r2 := oper(1, 2, add)
	fmt.Println(r2) // 3
	r3 := oper(1, 2, sub)
	fmt.Println(r3) // -1
	r4 := oper(8, 4, func(i int, i2 int) int {
		if (i == 0) {
			fmt.Println("除数不能为0")
			return 0
		}
		return i / i2
	})
	fmt.Println(r4)  // 2
}
//高阶函数,可以接受一个函数作为一个参数
func oper(a, b int, fun func(int, int) int) int {
	r := fun(a, b)
	return r
}
func add(a, b int) int {
	return a + b
}

func sub(a, b int) int {
	return a - b
}

十二、闭包

/*
一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量
并且该外层函数的返回值就是这个内层函数
这个内层函数和外层函数的局部变量,统称为闭包结构

局部变量的生命周期就会发生改变 正常的局部变量会随着函数的调用而创建
随着函数的结束而销毁 但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁 因为内层函数还在使用
*/

func main() {
	r1 := increment()
	fmt.Println(r1)  // 0x22e680

	v1 := r1()
	fmt.Println(v1) // 1

	v2 := r1()
	fmt.Println(v2) // 2

	r2 := increment()
	v3 := r2()
	fmt.Println(v3) // 1
}

func increment() func() int {
	//局部变量i
	i := 0
	//定义一个匿名函数,给变量自增并返回
	fun := func() int {
		i++
		return i
	}
	return fun
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值