17、函数

1.是什么?

函数就是执行特定任务的代码块

2.函数的意义

  • 避免重复的代码
  • 增强程序的扩展性

3.函数的使用步骤

  • step1 : 函数的定义,也叫声明
  • step2 : 函数的调用,就是执行函数中的代码

4.函数的语法

func funcName (paramName1 type1,paramName2 type2,......)(output1 type1,output2 type2){
// 这里是处理逻辑的代码
// 返回多个值
return val1,val2.....
}

func : 定义函数的关键字
funcName : 函数的名称
() : 函数的标志
参数列表 : 形式参数用于接收外部传入的实际参数
返回值列表 : 函数执行后返回给调用出的结果
注意:可以有多个返回值

5.函数注意事项

  • 函数必须先定义,在调用;如果不定义:undefined:funcName
  • 定义了的函数就去使用它不然没意义
  • 函数名不能重复
  • main() 是一个特殊的函数,作为程序的入口,由系统自动调用,而其他函数则是通过程序员手动通过函数名调用

6.函数简单使用

/**
 * @author ly (个人博客:https://www.cnblogs.com/qbbit)
 * @date 2023/5/2  14:55
 * @tags 喜欢就去努力的争取
 */
package main

import "fmt"

func main() {

	sum := 0
	for i := 1; i <= 10; i++ {
		sum += i
	}
	fmt.Println(sum)

	// 调用函数的方式实现
	res := getSum(100)
	fmt.Printf("1-100的累加和为:%d \n", res)
}

func getSum(num int) (res int) {
	sum := 0
	for i := 1; i <= num; i++ {
		sum += i
	}
	return sum
}

7.函数的参数

  • 形式参数:函数定义时,用于接收外部传入的数据,叫做形式参数,也叫形参
  • 实际参数:调用函数时,传给形参的实际数据,叫做实际参数,也叫是实参

函数的调用:

  • 函数名必须匹配
  • 实参与形参必须一一对应:顺序,个数,类型

8.可变参数

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

func add2(nums ...int) {
	sum := 0
	for _, v := range nums {
		sum += v
	}
	fmt.Printf("%T\n", nums)
	fmt.Printf("%d\n", sum)
}

注意事项:

  • 如果一个函数的参数是可变参数,同事含有其他参数时,可变参数必须放在最后
  • 一个函数只能有一个可变参数

9.参数的传递

数据类型:

  • 按照数据类型:
    • 基本数据类型:
      int float string bool
    • 复合数据类型
      array slice map struct interface ...
  • 按照数据的存储特点来分:
    • 值类型的数据:操作的是数值本身
      int float64 bool string array
    • 引用类型的数据:操作的是数据的地址
      slice map chan

参数传递:

  • 值传递:传递的是数据的副本。修改数据,对于原始的数据没有影响。
    基本类型,值类型数据,array,struct

  • 引用传递:传递的是数据的地址。会出现多个变量指向同一块内存
    应用类型的数据,slice,map,chan

/**
 * @author ly (个人博客:https://www.cnblogs.com/qbbit)
 * @date 2023/5/4  21:05
 * @tags 喜欢就去努力的争取
 */
package main

import "fmt"

func main() {
	// 演示数据是值传递
	arr1 := [3]int{1, 2, 3}
	fmt.Println("array调用函数前:", arr1)
	fun1(arr1)
	fmt.Println("array调用函数后:", arr1)

	// 演示切片是引用传递
	slice1 := []string{"zs", "ls", "ww"}
	fmt.Println("slice调用函数前:", slice1)
	fun2(slice1)
	fmt.Println("slice调用函数后:", slice1)

	// 演示map是引用传递
	map1 := make(map[int]string)
	map1[0] = "JavaScript"
	map1[1] = "Java"
	map1[2] = "Go"
	fmt.Println("map调用函数前:", map1)
	fun3(map1)
	fmt.Println("map调用函数后:", map1)

}

func fun1(arr [3]int) {
	fmt.Println("修改前的数组:", arr)
	arr[0] = 100
	fmt.Println("修改后的数组:", arr)
}

func fun2(sl []string) {
	fmt.Println("修改前的切片:", sl)
	sl[0] = "ly"
	fmt.Println("修改后的切片:", sl)
}

func fun3(m1 map[int]string) {
	fmt.Println("修改前的map", m1)
	m1[0] = "Python"
	fmt.Println("修改前的map", m1)
}

10.函数的返回值

一个函数被调用后,返回给调用出的执行结果,叫做函数的返回值。调用处需要用变量接收返回值

/**
 * @author ly (个人博客:https://www.cnblogs.com/qbbit)
 * @date 2023/5/4  22:05
 * @tags 喜欢就去努力的争取
 */
package main

import "fmt"

func main() {
	/**
		调用函数,获取返回值
		值得注意的是,go语言中支持多返回...
	*/
	sum, i := getSum2()
	fmt.Println(sum, i)

	sum2, i2 := getSum3(100)
	fmt.Println(sum2, i2)
}

func getSum2() (int, int) {
	sum := 0
	i := 1
	for ; i <= 10; i++ {
		sum += i
	}
	return sum, i
}

func getSum3(num int) (sum, i int) {
	for ; i <= num; i++ {
		sum += i
	}
	return sum, i
}

(1)一个函数可以有多个返回值
res1, res2 := rectangle(5, 10)
fmt.Println("周长:", res1)
fmt.Println("面积:", res2)

res3, res4 := rectangle(8, 10)
fmt.Println("周长:", res3)
fmt.Println("面积:", res4)

// 求矩形的周长和面积
func rectangle(len, wid float64) (float64, float64) {
	perimeter := (len + wid) * 2
	area := len * wid
	return perimeter, area
}

// 进阶写法
func rectangle2(len, wid float64) (perimeter, area float64) {
	perimeter = (len + wid) * 2
	area = len * wid
	return perimeter, area
}

11.return语句

一个函数的定义上有返回值,那么函数中必须使用return语句,将结果返回给调用处
函数返回的结果必须和函数定义的一致:类型,个数,顺序
作用:

  • 将函数的结果返回给调用处
  • 同事结束了该函数的执行

12.空白标识符: _

用于舍弃数据的

res5, _ := rectangle(8, 10)
fmt.Println("周长:", res5)
fmt.Println("不需要面积")

13.函数中变量的作用域

作用域:变量可以使用的范围

  • 局部变量:函数内部定义的变量,就叫做局部变量
    • 变量定义在哪儿,就只能在哪个范围内使用,超出作用范围,我们可以认为变量被销毁了
  • 全局变量:函数外部定义的变量,就叫做全局变量
    • 所有的函数都可以使用,而且共享这一份数据
/**
 * @author ly (个人博客:https://www.cnblogs.com/qbbit)
 * @date 2023/5/9  0:50
 * @tags 喜欢就去努力的争取
 */
package main

import "fmt"

// 全局变量
var num = 200

func main() {
	fun5()
	fmt.Println(num)
}

func fun5() {
	// 局部变量
	num := 100
	fmt.Println(num)
}

14.递归函数

/**
 * @author ly (个人博客:https://www.cnblogs.com/qbbit)
 * @date 2023/5/11  21:47
 * @tags 喜欢就去努力的争取
 */
package main

import "fmt"

func main() {

	/**
	递归函数
	求1-5的和?
	*/
	sum := diGuiSum(5)
	fmt.Printf("%T,%d\n", sum, sum)

	sequence := fibonacciSequence(100)
	fmt.Println(sequence)
}

func diGuiSum(num int) (sum int) {
	if num == 1 {
		return num
	}
	return num + diGuiSum(num-1)
}

/*
*
1 1 2 3 5 8 13 21
*/
func fibonacciSequence(num int) int {
	if num == 1 || num == 2 {
		return 1
	}
	return fibonacciSequence(num-1) + fibonacciSequence(num-2)
}
posted @   我也有梦想呀  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示