Go语言中的函数(重点)

入门简单精通难

函数式编程

什么是函数

  • 函数就是一段代码的集合
  • go语言中至少要有一个 main函数
  • 函数需要有一个名字,独立定义的情况下。见名知意
  • 函数可能需要有一个结果,也可能没有
func printHelloWorld() {
   fmt.Println("Hello,world")
}

image-20230209204517869

函数和方法完全是不一样的东西,面向对象里面才有方法

函数的具体定义

  • 无参无返回值
  • 有一个参数的函数
  • 有两个 or 多个参数的函数
  • 有一个返回值的函数
  • 有两个 or 多个返回值的函数
package main

import "fmt"

/*
*
- 无参无返回值
- 有一个参数的函数
- 有两个 or 多个参数的函数
- 有一个返回值的函数
- 有两个 or 多个返回值的函数
*/
func main() {
   m := max(123123123, 12312312312312)
   fmt.Println(m)
}

/*
func 函数名(参数1,参数2) 返回值类型 {
   // 代码逻辑

   return xxx
}
*/
// 定义一个稍微复杂一点的函数
// 比大小的函数 max ,两个数字比大小
// max函数,需要两个参数,int 类型的,比完大小之后我希望返回大的那一个数值
func max(num1 int, num2 int) int {
   var result int
   if num2 > num1 {
      result = num2
   } else {
      result = num1
   }
   // return返回结果
   return result
}

image-20230209205707923

多个返回值(重点)

package main

import "fmt"

func main() {
   a, b := swap("feige", "kuangshen")
   fmt.Println(a, " ", b)
}

// 返回多个返回值的函数定义
// 案例:交换两个string
// 有多个返回值的情况下,返回值用括号括起来
func swap(x string, y string) (string, string) {
   return y, x
}

多个返回的案例

package main

import "fmt"

func main() {
	_, _, _, r4 := fun2(2, 4)
	fmt.Println(r4)
}

// 周长、面积案例  (长方形 ... 长、宽)
// 返回多个值,需要括号,需要表明返回值类型,返回值也可以命名
// return的结果值命名和定义函数返回值的命名无关.
func fun1(len, wid float64) (zc float64, area float64) {
	area = len * wid
	zc = (len + wid) * 2
	fmt.Println("zc:", zc)
	fmt.Println("area:", area)
	// 1、return 如果直接定义了,那么返回结果按照 return 的顺序
	// 2、直接调用return不带结果,那么则返回 函数返回值定义的顺序进行结果返回。
	return
}

func fun2(len, wid float64) (float64, float64, float64, float64) {
	area := len * wid
	zc := (len + wid) * 2
	fmt.Println("zc:", zc)
	fmt.Println("area:", area)
	// 1、return 如果直接定义了,那么返回结果按照 return 的顺序
	// 2、直接调用return不带结果,那么则返回 函数返回值定义的顺序进行结果返回。
	return area, zc, 1, 3
}

工具:怎么用看自己

可变参数

package main

import "fmt"

func main() {
   fmt.Println(getSum())
}

// 可变参数: 一个函数的参数类型确定,参数的个数不确定,可以使用可变参数
// 可变参数如果有多个参数必须放在最后一个参数

// 求和 , 参数是可变的,int
func getSum(nums ...int) int {
   sum := 0
   fmt.Println("可变参数的长度为:", len(nums))
   for i := 0; i < len(nums); i++ {
      fmt.Println("可变参数", i, ":", nums[i])
      // 取出来
      //sum = sum + nums[i]
      sum += nums[i]
   }
   return sum
}

// 接收多个参数 nums 可变参数
// 使用下标来接收,下标是从0开始的
// nums : 100,200,300,400,500
// nums[0] = 100
// nums[1] = 200
// nums[2] = 300

// 了解传递了多少个数字  len()函数,获取可变参数的长度

参数的传递细节(留空)

  • 引用传递 ( 切片 )
  • 值传递 ( 数组 )

函数中作用域

package main

import "fmt"

// 函数作用域
// 局部变量
// 1、函数内部定义的变量,只能在函数内部调用
// 全部变量(全局变量)
// 1、函数外部定义的变量,默认我们定义在上面,方便文件统一查看和管理全局变量
var num int = 1

func main() {
	temp := 100
	// 定义一个只在 if 中生效的变量 if 临时变量(a,b := 1,2);条件判断{}
	// 小作用域可以用到大作用域中的变量,反之则不行。
	// 对于很多一次性的变量,都可以这么写
	if a := 1; a <= 10 {
		fmt.Println(temp)
		fmt.Println(num)
		fmt.Println(a)
		// 就近原则
		if a := 2; a <= 10 {
			fmt.Println(a)
		}
	}
	fmt.Println(num)
}

func f1() {
	fmt.Println(num)
}
func f2() {

}

递归函数(小难点)

package main

import "fmt"

/*
定义:一个函数自己调用自己,就叫做递归函数
注意:递归函数需要有一个出口,逐渐向出口靠近,没有出口就会形成死循环。
*/
func main() {
	// overflows 栈溢出
	sum := getSum2(1000000000)
	fmt.Println(sum)
}
func getSum2(n int) int {
	fmt.Println(n)
	if n == 1 {
		return 1
	}
	return getSum2(n-1) + n
}

// 假设 getSum(5)

// 求和 sum  1 + 2 + 3 + 4 + 5
// getSum(5)☟=15
//      getSum(4)☟=10 + 5
//          getSum(3)☟=6 + 4
//               getSum(2)☟=3 + 3
// //                getSum(1)=1 + 2

image-20230209215533739

回顾今日

  • 作业:如何面对一些简单题目
    • 分析需求
    • 拆分需求(if、for实现的一个逻辑)
    • 按照自己拆分的步骤,逐步实现
  • 什么是函数。函数定义
  • 多个返回值的函数
  • 多个参数、可变参数 …
  • 参数的作用域( 小范围的可以用大范围的变量,反之则不行 )
  • 递归函数(函数自己调用自己,用假设法来解决问题,可能会导致 overflow … ,递归是需要有尽头)