6.go语言函数

Go语言中的函数是组织代码的最小单元,用于封装一段代码,完成特定的功能。函数的使用可以减少代码冗余,提高代码的可读性和可维护性。

函数的基本定义和语法

在Go语言中,定义一个函数的基本语法如下:

func functionName(parameter1 type1, parameter2 type2, ...) (returnType, returnType...){

// 函数体return value1,value2... // 返回值

}

  • func:关键字用于定义函数。

  • functionName:函数名,用于唯一标识该函数。

  • parameter1 type1, parameter2 type2, ...:参数列表,函数可以接收零个或多个参数。每个参数由参数名和参数类型组成,多个参数之间使用逗号分隔。

  • returnType:返回类型,指定函数的返回值的数据类型。可以返回零个或多个值

  • return value:返回值,如果有返回值,则需要使用return语句将结果返回给调用者。

如果没有返回值,可以不写 return。如果写了,代表退出整个函数。

命名返回值

go语言支持为返回值命名。这些命名的返回值可以在函数体内部直接使用,而不需要显式地返回它们。这种方式特别适用于在函数执行过程中逐步构建或计算返回值,或者在满足特定条件时提前返回。

func sum(a, b int) (result int) {result = a + b // 直接赋值给命名返回值if result >= 0 {return // 提前返回,此时 result 自动返回}// 可以继续处理其他逻辑。比方返回值小于0,打印一句提醒,并把结果处理成正数。fmt.Println("您的计算结果小于0,已经为您取绝对值")result = result * -1return // 最终返回 result
}func main() {fmt.Println(sum(5, 7))  // 输出: 12fmt.Println(sum(-3, -7)) // 输出: (您的计算结果小于0,已经为您取绝对值  10)
}

函数的调用方式

函数的调用是通过函数名加上括号实现的。如果函数有参数,调用时需要在括号内传入实际的参数值。例如:

func add(a int, b int) int {
return a + b
}
func main() {result := add(3, 5) // 调用add函数,传入3和5作为参数fmt.Println("3 + 5 =", result) // 输出结果
}

定义多返回值函数

你可以在函数定义时,通过在参数列表后直接指定返回值的类型来实现多返回值。每个返回值类型之间用逗号分隔。

使用函数时候,你只对函数的某些返回值感兴趣,可以使用下划线(_)来忽略不需要的返回值。

func divide(a, b int) (int, int) {r := a / breturn r, a % b // 可以使用变量 返回,也可以使用表达式计算结果返回
}func main() {_, remainder := divide(10, 3) // 只关心余数,忽略商数fmt.Println("Remainder:", remainder)
}

//注意,定义无返回值函数,不能使用变量接收 函数的返回。

可变参数

go语言,不支持给参数设置默认值。

但是支持,可变参数。使用...type 定义。把收集到多余的实参,存放到对应类型的切片中。

匿名函数

匿名函数是通过 func 关键字直接定义的,没有指定函数名。你可以将匿名函数赋值给一个变量,或者直接调用它。

  myFunction := func(x, y int) int {return x + y}// 调用匿名函数result := myFunction(5, 10)fmt.Println(result) // 输出: 15// 直接调用匿名函数result := func(x, y int) int {return x + y}(5, 10)fmt.Println(result) // 输出: 15

go函数作为参数类型

函数作为参数的使用方式非常简单,我们只需要将需要传递的函数作为参数传递给另一个接受这个函数作为参数的函数即可。

如果逻辑代码很复杂,上边代码就很 臃肿,不容易让人理解。我们可以。把函数签名声明为一个类型。

函数闭包

闭包通常涉及到定义一个函数,该函数在其内部定义了另一个函数,并将该函数返回出去,返回出去的函数可以访问外部函数的变量。

package mainimport "fmt"func outerFunction() func() int {var x = 10return func() int {x++return x}
}func main() {myClosure := outerFunction() // 获取闭包fmt.Println(myClosure()) // 输出: 11fmt.Println(myClosure()) // 输出: 12
}

函数总结

函数的特性

Go语言的函数具有以下特性:

  • 支持不定参数:可以使用...来表示不定参数,允许函数接收任意数量的参数。

  • 支持多返回值:可以返回多个结果,例如错误信息和结果值。

  • 支持命名返回参数:可以在函数内部给返回值命名,方便处理返回值。

  • 支持匿名函数和闭包:可以定义匿名函数并在需要时调用。

  • 函数也是一种类型:一个函数可以赋值给变量,实现更灵活的调用。

  • 不支持嵌套、重载和默认参数:Go语言不支持在一个包中定义两个名字相同的函数、函数的重载以及默认参数

defer 延迟调用

defer的核心作用是延迟调用函数或方法,

这意味着defer语句所指定的函数调用会被推迟到当前函数返回之前执行,无论函数是正常返回还是因发生异常而返回。

当一个函数中有多个defer语句时,它们会按照后进先出的顺序执行。也就是说,最后一个defer语句所指定的函数会最先被调用,而第一个defer语句所指定的函数最后被调用。例如:

递归是一种常见的编程技术,它允许函数直接或间接地调用自身。

递归的核心思想在于将一个大问题分解为若干个小问题,然后逐步解决这些小问题,最终达到解决整个大问题的目的。

特点:

  自身调用:原问题可以分解为子问题,子问题和原问题的求解方法是一致的,即都是调用自身的同一个函数。

  终止条件:递归必须有一个终止的条件,即不能无限循环地调用本身。

  简洁但效率不高:递归算法解题通常显得很简洁,但递归算法解题的运行效率较低,因为数据存入堆栈中,等待函数调用结束后再取出,会增加性能消耗。另外堆栈还存在溢出的风险。

计算阶乘的递归函数:

func factorial(n uint) uint {

        if n == 0 {

                return 1 // 递归终止条件

           }

        return n * factorial(n-1) // 调用自身

}

  • . 构建递归调用堆栈

每次函数调用自身时,一个新的调用实例被推入调用堆栈。直到达到基本情况,才开始从堆栈中逐个返回结果。这个过程类似于函数调用链的构建和解析。

  • 避免无限递归和栈溢出

正确设置递归终止条件,确保每个递归函数都有清晰定义的基本情况是非常重要的,否则可能会导致无限递归,进而耗尽栈空间,导致程序崩溃(栈溢出)。

  • 优化递归(尾递归优化)

在某些情况下,可以通过尾递归优化来提高效率。尾递归是指在函数的最后一步调用自身的情况。Go语言在某些情况下可以优化尾递归,使其表现得像循环一样,从而避免栈溢出。

递归是实现诸如树遍历、排序算法(如快速排序)、 斐波那契数列,图与树的遍历搜索等多种算法的有效方式

快速排序的实现

package mainimport ("fmt"
)// quickSort 对数组 arr 进行快速排序
func quickSort(arr []int) []int {if len(arr) < 2 {// 基本情况:数组只有一个元素或为空,无需排序return arr}left, right := 0, len(arr)-1// 选择最右边的元素作为基准值pivot := right// 将数组分为小于基准和大于基准的两部分newPivot := partition(arr, left, right, pivot)// 递归排序左右两部分quickSort(arr[:newPivot])quickSort(arr[newPivot+1:])return arr
}// partition 对数组进行划分,返回新的基准位置
func partition(arr []int, left, right, pivot int) int {pivotValue := arr[pivot]// 将基准值交换到最右边,即最后一个位置arr[pivot], arr[right] = arr[right], arr[pivot]storeIndex := leftfor i := left; i < right; {if arr[i] < pivotValue {arr[i], arr[storeIndex] = arr[storeIndex], arr[i]storeIndex++}i++}// 将基准值放到正确的位置上arr[storeIndex], arr[right] = arr[right], arr[storeIndex]return storeIndex // 返回新的基准位置
}func main() {arr := []int{10, 7, 8, 9, 1, 5}fmt.Println("Original array:", arr)sortedArr := quickSort(arr)fmt.Println("Sorted array:  ", sortedArr)
}

go内置排序函数

sort.Slice进行通用排序

从Go 1.8开始,sort包引入了Slice函数,它允许你直接对切片进行排序,而无需实现任何接口。

package mainimport ("fmt""sort"
)func main() {a := []int{3, 1, 4, 1, 5, 9}sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) // 使用闭包进行排序逻辑定义fmt.Println(a) // 输出: [1 1 3 4 5 9]
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/73539.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/73539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCould微服务架构之Docker(4)

Docker ce是社区版。 安装docker之前&#xff0c;先安装yum-util 。 安装docker之前&#xff0c;一定要先关闭防火墙。

Keepalived 实现高可用方案

Keepalived简介 ‌Keepalived‌ 是一个基于 ‌VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议‌的高可用性解决方案&#xff0c;主要用于实现‌服务故障自动切换&#xff08;Failover&#xff09;和负载均衡‌。通过管理虚拟 IP&#xff08;VIP&#xf…

WPS JS宏编程教程(从基础到进阶)--第二部分:WPS对象模型与核心操作

第二部分&#xff1a;WPS对象模型与核心操作 WPS对象的属性、方法、集合 工作簿对象常用表达方式工作表对象常用表达方式单元格对象常用表达方式 单元格操作实战 单元格复制与重定位单元格偏移与尺寸调整 颜色设置专题 索引颜色与RGB颜色按条件动态设置单元格颜色 第二部分&…

基于DrissionPage的TB商品信息采集与可视化分析

一、项目背景 随着电子商务的快速发展,淘宝作为中国最大的电商平台之一,拥有海量的商品信息。这些数据对于市场分析、用户行为研究以及竞争情报收集具有重要意义。然而,由于淘宝的反爬虫机制和复杂的页面结构,直接获取商品信息并不容易。尤其是在电商行业高速发展的今天,商…

【003安卓开发方案调研】之ReactNative技术开发安卓

基于2025年最新行业动态和搜索资料&#xff0c;以下是针对国内使用React Native&#xff08;RN&#xff09;开发安卓应用的深度分析&#xff1a; 一、技术成熟度评估 1. 核心架构升级 新架构全面普及&#xff1a;2024年起&#xff0c;React Native的 新架构&#xff08;Fabri…

JS数组方法

数组方法 一、数组 JavaScript 数组的大小是可调整的&#xff0c;并且可以包含不同 数据类型。&#xff08;当不需要这些特性时&#xff0c;请使用 类型数组。&#xff09; 注&#xff1a;JavaScript 类型数组是类似数组的对象&#xff0c;它提供了一种在内存缓冲区中读取和写…

【一起学Rust | Tauri2.0框架】深入浅出 Tauri 2.0 应用调试:从新手到专家的蜕变

前言 Tauri 是一款备受瞩目的跨平台桌面应用开发框架&#xff0c;它允许开发者使用 Web 技术栈&#xff08;HTML、CSS、JavaScript&#xff09;构建高性能、安全的原生应用。Tauri 2.0 的发布带来了诸多令人兴奋的新特性和改进&#xff0c;进一步提升了开发体验和应用性能。然…

Python项目-基于Python的网络爬虫与数据可视化系统

1. 项目简介 在当今数据驱动的时代&#xff0c;网络爬虫和数据可视化已成为获取、分析和展示信息的重要工具。本文将详细介绍如何使用Python构建一个完整的网络爬虫与数据可视化系统&#xff0c;该系统能够自动从互联网收集数据&#xff0c;进行处理分析&#xff0c;并通过直观…

TCP/IP三次握手的过程,为什么要3次?

一&#xff1a;过程 第一次&#xff08;SYN&#xff09;&#xff1a; 客户端发送一个带有SYN标志的TCP报文段给服务器&#xff0c;设置SYN1&#xff0c;并携带初始序列号Seqx&#xff08;随机值&#xff09;&#xff0c;进入SYN_SENT状态。等待服务器相应。 第二次&#xff08…

消息队列性能比拼: Kafka vs RabbitMQ

本内容是对知名性能评测博主 Anton Putra Kafka vs RabbitMQ Performance 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 简介 在本视频中&#xff0c;我们将首先比较 Apache Kafka 和传统的 RabbitMQ。然后&#xff0c;在第二轮测试中&#xff0c;会将 Kaf…

打磨和修改:字帖自动生成

功能增加一些。 一个人和大语言模型对话的结果。 不过是重复性劳动&#xff0c;特别需要创意的地方还是不容易做到。

电脑干货:万能驱动--EasyDrv8

目录 万能驱动EasyDrv8 功能介绍 主程序界面 驱动解压与安装 PE环境支持 系统部署环境 桌面环境一键解决方案 万能驱动8电脑版是由IT天空出品的一款智能识别电脑硬件并自动安装驱动的工具&#xff0c;一般又称为it天空万能驱动&#xff0c;万能驱动vip版&#xff0c;简称…

LeetCode热题100JS(79/100)第十五天|347|295|121|55|45

347. 前 K 个高频元素 题目链接&#xff1a;347. 前 K 个高频元素 难度&#xff1a;中等 刷题状态&#xff1a;1刷 新知识&#xff1a; 解题过程 思考 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 没思路&#xff0c;看答案 题解分析 参考题解链接&#xff1a…

Sentinel 限流利器(功能以及源码解析)

Sentinel简介 Sentinel是阿里开源的一款面向分布式、多语言异构化服务架构的流量治理组件。 主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 核心概念 资源 资源是…

子数组 之 logTrick算法,求解或,与,LCM,GCD

文章目录 gcd的问题最大公约数 求解子数组的&,|,lcm,gcd的最值or计数问题&#xff0c;如果采用暴力的做法&#xff0c;那么时间复杂度会来到o(n^2),其实在求解的过程中&#xff0c;会出现很多的结果不变的情况&#xff0c;所以我们就可以提前结束 存在一定的单调性&#x…

How to use pgbench to test performance for PostgreSQL?

pgbench 是一个用于测试 PostgreSQL 数据库性能的基准测试工具。通过模拟多个客户端并发执行 SQL 查询&#xff0c;它可以帮助你评估数据库的性能。以下是使用 pgbench 的基本步骤&#xff1a; 安装 pgbench pgbench 是 PostgreSQL 的一部分&#xff0c;因此在安装 PostgreSQ…

应用服务接口第二次请求一直pending问题

目录 一、问题背景二、问题排查过程三、解决方案四、总结 一、问题背景 升级内容发布到灰度环境&#xff0c;验证相关服务&#xff0c;查看接口调用日志&#xff0c;发现第一次请求正常&#xff0c;第二次相同接口请求就一直pending&#xff0c;其他服务也是如此 二、问题排查…

嵌入式八股RTOS与Linux---网络系统篇

前言 关于计网的什么TCP三次握手 几层模型啊TCP报文啥的不在这里讲,会单独分成一个计算机网络模块   这里主要介绍介绍lwip和socket FreeRTOS下的网络接口–移植LWIP 实际上FreeRTOS并不自带网络接口,我们一般会通过移植lwip协议栈让FreeRTOS可以通过网络接口收发数据,具体可…

推荐一款好看的 vue3 后台模板

SoybeanAdmin 项目简介 SoybeanAdmin 是一个基于最新前端技术栈的清新、优雅、高颜值且功能强大的后台管理模板。它采用 Vue3, Vite5, TypeScript, Pinia, NaiveUI 和 UnoCSS 构建&#xff0c;为开发者提供了一个现代化、高效且易于扩展的后台管理系统解决方案。 主要特点&am…

【django】1-1 django构建web程序的基础知识

文章目录 1 构建web应用的基础知识1.1 互联网相关的概念1.2 互联网协议DNS(域名系统)IP协议(互联网络协议)TCP(传输控制协议)HTTP(超文本传输协议)SSL(安全套接字层)TLS(传输层安全) 1.3 URL 2 web程序2.1 web程序的本质2.2 web框架的设计模式1.2.1 经典的MVC设计模式1.2.2 Dja…