go语言学习 第5章:函数

news2025/6/6 9:33:03

第5章:函数

函数是编程中不可或缺的一部分,它封装了一段可重复使用的代码,用于执行特定的任务。在Go语言中,函数同样扮演着重要的角色。本章将详细介绍Go语言中函数的定义、调用、参数传递、返回值处理以及一些高级特性,如闭包和匿名函数。

一、函数的定义与调用

(一)函数的定义

在Go语言中,函数的定义使用func关键字。基本语法如下:

func 函数名(参数列表) 返回值列表 {
    // 函数体
}
  • 函数名:函数的名称,用于调用函数。
  • 参数列表:函数接收的输入参数,可以有多个参数,也可以没有参数。
  • 返回值列表:函数执行完成后返回的值,可以有多个返回值,也可以没有返回值。
  • 函数体:函数的具体实现代码。
1. 无参数无返回值的函数
package main

import "fmt"

func sayHello() {
    fmt.Println("Hello, Golang!")
}

func main() {
    sayHello() // 调用函数
}
2. 带参数的函数
package main

import "fmt"

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

func main() {
    result := add(10, 20)
    fmt.Println("结果是:", result)
}
3. 多返回值的函数

Go语言支持函数返回多个值。例如:

package main

import "fmt"

func swap(a, b int) (int, int) {
    return b, a
}

func main() {
    x, y := swap(10, 20)
    fmt.Println("交换后的值:", x, y)
}

(二)函数的调用

函数的调用非常简单,只需要使用函数名并传递相应的参数即可。例如:

package main

import "fmt"

func main() {
    sayHello() // 调用无参数函数
    result := add(10, 20) // 调用带参数函数
    fmt.Println("结果是:", result)
    x, y := swap(10, 20) // 调用多返回值函数
    fmt.Println("交换后的值:", x, y)
}

二、参数传递

(一)值传递

在值传递中,函数接收的是参数的副本,对参数的修改不会影响原始变量。例如:

package main

import "fmt"

func modifyValue(a int) {
    a = 100
}

func main() {
    num := 10
    modifyValue(num)
    fmt.Println("修改后的值:", num) // 输出 10
}

(二)指针传递

在指针传递中,函数接收的是参数的地址,对参数的修改会影响原始变量。例如:

package main

import "fmt"

func modifyValue(a *int) {
    *a = 100
}

func main() {
    num := 10
    modifyValue(&num)
    fmt.Println("修改后的值:", num) // 输出 100
}

三、函数的高级特性

(一)匿名函数

匿名函数是没有名称的函数,可以在定义时直接调用,也可以赋值给变量后调用。例如:

package main

import "fmt"

func main() {
    // 定义并直接调用匿名函数
    result := func(a, b int) int {
        return a + b
    }(10, 20)

    fmt.Println("结果是:", result)

    // 将匿名函数赋值给变量
    add := func(a, b int) int {
        return a + b
    }

    fmt.Println("结果是:", add(30, 40))
}

(二)闭包

闭包是一个函数和其相关的引用环境的组合。闭包可以捕获外部变量,并在函数外部使用这些变量。例如:

package main

import "fmt"

func getCounter() func() int {
    var count int
    return func() int {
        count++
        return count
    }
}

func main() {
    counter := getCounter()
    fmt.Println(counter()) // 输出 1
    fmt.Println(counter()) // 输出 2
    fmt.Println(counter()) // 输出 3
}

(三)函数作为参数

在Go语言中,函数也是一种类型,可以作为参数传递给其他函数。例如:

package main

import "fmt"

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

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

func operate(a, b int, operation func(int, int) int) int {
    return operation(a, b)
}

func main() {
    result := operate(10, 5, add)
    fmt.Println("加法结果:", result) // 输出 15

    result = operate(10, 5, subtract)
    fmt.Println("减法结果:", result) // 输出 5
}

(四)函数作为返回值

函数不仅可以作为参数传递,还可以作为返回值。例如:

package main

import "fmt"

func getOperation(op string) func(int, int) int {
    if op == "add" {
        return func(a, b int) int {
            return a + b
        }
    } else if op == "subtract" {
        return func(a, b int) int {
            return a - b
        }
    }
    return nil
}

func main() {
    add := getOperation("add")
    fmt.Println("加法结果:", add(10, 5)) // 输出 15

    subtract := getOperation("subtract")
    fmt.Println("减法结果:", subtract(10, 5)) // 输出 5
}

四、函数的命名和文档

(一)函数命名

函数的命名应该清晰地反映其功能。通常使用驼峰命名法,首字母小写表示私有函数,首字母大写表示公有函数。例如:

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

func Add(a, b int) int {
    return a + b
}

(二)函数文档

在Go语言中,可以通过在函数定义前添加注释来为函数编写文档。这些注释会被go doc工具读取并生成文档。例如:

// Add returns the sum of a and b.
func Add(a, b int) int {
    return a + b
}

五、总结

本章详细介绍了Go语言中函数的定义、调用、参数传递、返回值处理以及一些高级特性,如闭包和匿名函数。函数是Go语言中非常重要的一个概念,它不仅可以让代码更加模块化,还可以通过高级特性实现一些复杂的逻辑。通过合理使用函数,可以使代码更加清晰、易读和易维护。

在接下来的章节中,我们将继续深入学习Go语言的其他特性,如错误处理、数组、切片、映射等。希望读者能够通过这些内容更好地掌握Go语言,提升编程技能。

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

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

相关文章

Glide NoResultEncoderAvailableException异常解决

首先将解决方法提出来:缓存策略DiskCacheStrategy.DATA。 使用Glide加载图片,版本是4.15.0,有天发现无法显示gif图片,原始代码如下: Glide.with(context).load(本地资源路径).diskCacheStrategy(DiskCacheStrategy.A…

无人机巡检智能边缘计算终端技术方案‌‌——基于EFISH-SCB-RK3588工控机/SAIL-RK3588核心板的国产化替代方案‌

一、方案核心价值‌ ‌实时AI处理‌:6TOPS NPU实现无人机影像的实时缺陷检测(延迟<50ms)‌全国产化‌:芯片、操作系统、算法工具链100%自主可控‌极端环境适配‌:-40℃~85℃稳定运行,IP65防护等…

相机--相机成像原理和基础概念

教程 成像原理 基础概念 焦距(物理焦距) 镜头的光学中心到感光元件之间的距离,用f表示,单位:mm;。 像素焦距 相机内参矩阵中的 fx​ 和 fy​ 是将物理焦距转换到像素坐标系的产物,可能不同。…

2025-0604学习记录17——文献阅读与分享(2)

最近不是失踪了!也不是弃坑了...这不是马上要毕业了嘛!所以最近在忙毕业论文答辩、毕业去向填报、户档去向填报等等,事情太多了,没顾得上博客。现在这些事基本上都解决完了,也有时间静下心来写写文字了~ 想要写的内容…

图解浏览器多进程渲染:从DNS到GPU合成的完整旅程

目录 浅谈浏览器进程 浏览器进程架构的演化 进程和线程关系图示 进程(Process) 线程(Thread) 协程(Coroutine) 进程&线程&协程核心对比 单进程和多进程浏览器 单进程浏览器​编辑 单进程…

【计算机网络】第3章:传输层—TCP 拥塞控制

目录 一、PPT 二、总结 TCP 拥塞控制详解 ⭐ 核心机制与算法 1. 慢启动(Slow Start) 2. 拥塞避免(Congestion Avoidance) 3. 快速重传(Fast Retransmit) 4. 快速恢复(Fast Recovery&…

idea不识别lombok---实体类报没有getter方法

介绍 本篇文章,主要讲idea引入lombok后,在实体类中加注解Data,在项目启动的时候,编译不通过,报错xxx.java没有getXxxx()方法。 原因有以下几种 1. idea没有开启lombok插件 2. 使用idea-2023…

SAP学习笔记 - 开发15 - 前端Fiori开发 Boostrap,Controls,MVC(Model,View,Controller),Modules

上一章讲了Fiori开发的准备,以及宇宙至简之HelloWorld。 SAP学习笔记 - 开发14 - 前端Fiori开发 HelloWorld-CSDN博客 本章继续学习 Fiori 开发的知识: Bootstrap,Controls,MVC(Model,View,Controller&a…

基于SDN环境下的DDoS异常攻击的检测与缓解

参考以下两篇博客,最后成功: 基于SDN的DDoS攻击检测和防御方法_基于sdn的ddos攻击检测与防御-CSDN博客 利用mininet模拟SDN架构并进行DDoS攻击与防御模拟(Ryumininetsflowpostman)_mininet模拟dos攻击-CSDN博客 需求 H2 模拟f…

如何轻松地将文件从 PC 传输到 iPhone?

传统上,您可以使用 iTunes 将文件从 PC 传输到 iPhone,但现在,使用 iTunes 已不再是唯一的选择。现在有多种不同且有效的方法可以帮助您传输文件。在今天的指南中,您可以找到 8 种使用或不使用 iTunes 传输文件的方法,…

Bresenham算法

一 Bresenham 绘直线 使用 Bresenham 算法,可以在显示器上绘制一直线段。该算法主要思想如下: 1 给出直线段上两个端点 ,根据端点求出直线在X,Y方向上变化速率 ; 2 当 时,X 方向上变化速率快于 Y 方向上变化速率&am…

【从GEO数据库批量下载数据】

从GEO数据库批量下载数据 1:进入GEO DataSets拿到所需要下载的数据的srr.list,上传到linux, 就可以使用prefetch这个函数来下载 2:操作步骤如下: conda 安装sra-tools conda create -n sra-env -c bioconda -c co…

day 44

使用DenseNet预训练模型对cifar10数据集进行训练 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms, models from torch.utils.data import DataLoader import matplotlib.pyplot as plt import os# 设置中文字体…

NER实践总结,记录一下自己实践遇到的各种问题。

更。 没卡,跑个模型休息好几天,又闲又急。 一开始直接套用了别人的代码进行实体识别,结果很差,原因是他的词表没有我需要的东西,我是用的医学文本。代码直接在github找了改的,用的是BERT的Chinese版本。 然…

微信小程序实现运动能耗计算

微信小程序实现运动能耗计算 近我做了一个挺有意思的微信小程序,能够实现运动能耗的计算。只需要输入性别、年龄、体重、运动时长和运动类型这些信息,就能算出对应的消耗热量。 具体来说,在小程序里,性别不同,身体基…

iTunes 无法备份 iPhone:10 种解决方法

Apple 设备是移动设备市场上最先进的产品之一,但有些人遇到过 iTunes 因出现错误而无法备份 iPhone 的情况。iTunes 拒绝备份 iPhone 时,可能会令人非常沮丧。不过,幸运的是,我们有 10 种有效的方法可以解决这个问题。您可以按照以…

LangChain4J 使用实践

这里写目录标题 大模型应用场景&#xff1a;创建一个测试示例AIService聊天记忆实现简单实现聊天记录记忆MessageWindowChatMemory实现聊天记忆 隔离聊天记忆聊天记忆持久化 添加AI提示词 大模型应用场景&#xff1a; 创建一个测试示例 导入依赖 <dependency><groupI…

【C++】—— 从零开始封装 Map 与 Set:实现与优化

人生的态度是&#xff0c;抱最大的希望&#xff0c;尽最大的努力&#xff0c;做最坏的打算。 —— 柏拉图 《理想国》 目录 1、理论基石——深度剖析 BSTree、AVLTree 与 RBTree 的概念区别 2、迭代器机制——RBTree 迭代器的架构与工程实现 3、高级容器设计——Map 与 Set…

内网穿透之Linux版客户端安装(神卓互联)

选择Linux系统版本 获取安装包 &#xff1a;https://www.shenzhuohl.com/download.html 这里以Ubuntu 18.04为例&#xff0c;其它版本方法类似 登录Ubuntu操作系统&#xff1a; 打开Ubuntu系统终端&#xff0c;更新版本 apt-get update 安装运行环境&#xff1a; 安装C 运…

开疆智能Profinet转Profibus网关连接CMDF5-8ADe分布式IO配置案例

本案例是客户通过开疆智能研发的Profinet转Profibus网关将PLC的Profinet协议数据转换成IO使用的Profibus协议&#xff0c;操作步骤如下。 配置过程&#xff1a; Profinet一侧设置 1. 打开西门子组态软件进行组态&#xff0c;导入网关在Profinet一侧的GSD文件。 2. 新建项目并…