GO语言基础笔记(二):控制结构与函数

1. 控制结构

1.1 if-else 结构
  • 基本形式if 条件判断后跟着一个代码块。如果条件为真,则执行该代码块。
  • else 语句:紧随 if 代码块后面,当 if 条件不成立时执行。
  • else if:可以在 ifelse 之间添加更多的条件判断。
package mainimport ("fmt"
)func main() {score := 85 // 假设这是一个成绩// 使用 if 判断成绩是否优秀if score >= 90 {fmt.Println("成绩优秀,等级:A")} else if score >= 80 {// 当成绩不满足第一个 if 条件(即小于90),但满足 else if 条件时执行fmt.Println("成绩良好,等级:B")} else if score >= 70 {fmt.Println("成绩合格,等级:C")} else if score >= 60 {fmt.Println("成绩及格,等级:D")} else {// 当所有其他条件都不满足时执行 else 块fmt.Println("成绩不及格,等级:F")}
}
  1. 条件清晰:每个ifelse if块的条件应该是互斥的,这样可以防止重复判断。
  2. 顺序安排:将最有可能发生的条件放在前面,可以提高代码效率。
  3. 避免嵌套过深:尽量减少if-else的嵌套深度,以保持代码的可读性。
  4. 条件简化:在条件判断中使用适当的逻辑运算符来简化表达式。
1.2 switch 结构
  • 基本用法switch 后跟一个表达式,然后是多个 case 分支。每个 case 后跟着要比较的值和执行的代码块。
  • 不带表达式的 switch:可以直接在 case 后使用条件表达式。
  • fallthrough 关键字:默认情况下,每个 case 执行完后自动跳出 switch,使用 fallthrough 可以强制执行下一个 case

 

package mainimport ("fmt"
)func main() {// 示例1:基本用法number := 3switch number {case 1:fmt.Println("数字是 1")case 2:fmt.Println("数字是 2")case 3:fmt.Println("数字是 3")default:fmt.Println("数字不是 1、2、3")}// 示例2:不带表达式的switchscore := 85switch {case score >= 90:fmt.Println("成绩优秀")case score >= 80:fmt.Println("成绩良好")case score >= 60:fmt.Println("成绩合格")default:fmt.Println("成绩不合格")}// 示例3:使用fallthroughmonth := 5switch month {case 3, 4, 5:fmt.Println("春季")fallthroughcase 6, 7, 8:fmt.Println("夏季")case 9, 10, 11:fmt.Println("秋季")case 12, 1, 2:fmt.Println("冬季")default:fmt.Println("未知的月份")}
}

 

  1. 明确case分支:每个case后面跟着一个或多个要比较的值和代码块。这使得代码逻辑清晰易懂。
  2. 使用default:当所有case都不匹配时,执行default分支。这是一个良好的编程习惯,可用于处理异常或未预期的情况。
  3. 不带表达式的switch:在某些情况下,不带表达式的switch可以替代多层嵌套的if-else,使得代码更加清晰。
  4. 谨慎使用fallthroughfallthrough关键字使得控制流穿越到下一个case,即使下一个case的条件不成立也会执行。使用时要非常小心,以避免逻辑错误。
1.3 for 循环
  • 基本结构:包括初始化语句、条件表达式和结束后的操作,格式为 for 初始化; 条件; 后续操作 {}
  • 条件循环:只有条件表达式的 for 循环。
  • 无限循环:省略所有元素的 for 循环将无限循环直到内部有 breakreturn

        1. 基本的for循环

package mainimport ("fmt"
)func main() {// 示例1:基本的for循环for i := 0; i < 5; i++ {fmt.Println("基本循环,当前索引:", i)}
}

         2. 条件循环

	// 示例2:条件循环j := 0for j < 5 {fmt.Println("条件循环,当前索引:", j)j++}

        3. 无限循环 

	// 示例3:无限循环k := 0for {if k == 3 {break // 当 k 等于 3 时退出循环}fmt.Println("无限循环,当前索引:", k)k++}
}

技巧性总结

  • 明确循环条件:在编写for循环时,始终清晰地定义循环的开始和结束条件。
  • 避免无限循环:在使用无限循环时,务必确保有一个明确的退出条件,以避免程序陷入死循环。
  • 代码简洁:尽量保持循环体内代码的简洁,这有助于提高代码的可读性和可维护性。

2. 函数

2.1 函数定义
  • 基本语法func 函数名(参数列表) (返回值列表) { 函数体 }
  • 参数列表:定义输入的类型和名称。
  • 返回值列表:可以是具名的也可以是非具名的,具名返回值在函数体开始时被自动初始化。
        基本函数定义
package mainimport ("fmt"
)// 无参数,无返回值的函数
func greet() {fmt.Println("Hello, Go!")
}func main() {greet() // 调用函数
}
         带参数的函数
// 带参数的函数
func add(x int, y int) int {return x + y
}func main() {result := add(5, 7) // 调用函数fmt.Println("结果:", result)
}
         具名返回值
// 具名返回值
func swap(x, y string) (a, b string) {a = yb = xreturn // 隐式返回a, b
}func main() {a, b := swap("hello", "world")fmt.Println(a, b) // 输出:world hello
}
//使用具名返回值可以提高代码的可读性,尤其是在函数有多个返回值时。
        非具名返回值 
// 非具名返回值
func divide(x, y float64) (float64, error) {if y == 0.0 {return 0.0, fmt.Errorf("不能除以零")}return x / y, nil
}func main() {result, err := divide(10.0, 0.0)if err != nil {fmt.Println("错误:", err)} else {fmt.Println("结果:", result)}
}
  • 清晰的参数和返回值:定义函数时,明确参数类型和返回值类型可以提高代码的可读性和健壮性。
  • 合理使用具名返回值:在函数返回多个值或需要说明返回值意义时使用具名返回值。
  • 错误处理:在可能出现错误的场合,返回一个错误值作为函数的一部分,以便于错误处理。
2.2 函数使用
  • 调用函数:使用函数名和传入相应的参数。
  • 返回值:可以返回一个或多个值。
  • 匿名函数:没有函数名的函数,可以在定义后立即调用。
        调用普通函数
package mainimport ("fmt"
)// 定义一个简单的相加函数
func add(x, y int) int {return x + y
}func main() {// 调用函数并处理返回值result := add(5, 7)fmt.Println("相加结果:", result)
}
         处理多个返回值
// 定义一个函数,返回两个值
func divideAndRemainder(x, y int) (int, int) {return x / y, x % y
}func main() {// 接收两个返回值quotient, remainder := divideAndRemainder(7, 2)fmt.Println("商:", quotient, "余数:", remainder)
}
         使用匿名函数
func main() {// 定义并立即调用匿名函数func(msg string) {fmt.Println(msg)}("Hello, Go!")
}
  • 函数调用的准确性:在调用函数时,确保参数的正确性和返回值的正确处理。
  • 处理多返回值:在函数返回多个值时,可以通过多个变量来接收这些值。
  • 匿名函数的灵活性:匿名函数是一种灵活的工具,可以用于立即执行一些操作,或作为高阶函数的参数。

2.3回调函数
package mainimport ("fmt"
)// 定义回调函数类型,这种函数接受一个整数并返回一个整数
type callbackFunc func(int) int// processSlice 函数接受一个整数切片和一个回调函数
// 它对切片中的每个元素应用回调函数,并返回新的切片
func processSlice(slice []int, callback callbackFunc) []int {var result []intfor _, value := range slice {processedValue := callback(value)result = append(result, processedValue)}return result
}// 具体的回调函数,例如将整数乘以2
func multiplyByTwo(n int) int {return n * 2
}func main() {// 定义一个整数切片slice := []int{1, 2, 3, 4, 5}// 使用 multiplyByTwo 回调函数处理切片processedSlice := processSlice(slice, multiplyByTwo)// 打印原始和处理后的切片fmt.Println("原始切片:", slice)fmt.Println("处理后的切片:", processedSlice)
}

 

        在这个示例中,我们定义了一个事件管理器eventManager,它允许注册回调函数并在事件触发时调用这些函数。 

package mainimport ("fmt"
)// 定义回调函数类型
type eventCallback func()// 事件管理器
type eventManager struct {callbacks []eventCallback
}// 注册事件的回调函数
func (m *eventManager) registerCallback(callback eventCallback) {m.callbacks = append(m.callbacks, callback)
}// 触发事件,调用所有注册的回调函数
func (m *eventManager) triggerEvent() {for _, callback := range m.callbacks {callback()}
}func main() {// 创建事件管理器实例manager := eventManager{}// 注册一些回调函数manager.registerCallback(func() {fmt.Println("第一个事件回调被触发")})manager.registerCallback(func() {fmt.Println("第二个事件回调被触发")})// 触发事件manager.triggerEvent()
}

 

 2.3 go的其他函数机制
  1. 多返回值:Go函数可以返回多个值,这在错误处理和数据返回方面非常有用。

  2. 命名返回值:函数可以有命名的返回值,这些返回值在函数开始时就被声明,可以在函数体内直接使用。

  3. 变参函数(Variadic Functions):Go支持变参函数,允许函数接受任意数量的参数。

  4. 匿名函数和闭包(Closures):Go支持匿名函数,这些函数可以定义在其他函数内部,并可以访问外部函数的变量,形成闭包。

  5. 延迟调用(Defer):Go的defer语句会延迟函数的执行直到包含它的函数结束。

  6. 高阶函数(Higher-Order Functions):在Go中,函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。

  7. 方法(Methods):Go允许定义在结构体(或任意类型)上的函数,称为方法。这提供了一种面向对象的方式来处理数据。

  8. 接口(Interfaces):虽然不是直接的函数机制,但接口在Go中用于定义函数的行为契约,为多态和模块化设计提供支持。

  9. 递归函数(Recursive Functions):函数可以调用自身,这是在处理某些算法时非常有用的。

  10. 并发的函数调用(Goroutines):通过goroutines,Go支持在轻量级线程中并发执行函数。

 

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

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

相关文章

Pinely Round 3 (Div. 1 + Div. 2)(A~D)(有意思的题)

A - Distinct Buttons 题意&#xff1a; 思路&#xff1a;模拟从&#xff08;0,0&#xff09;到每个位置需要哪些操作&#xff0c;如果总共需要4种操作就输出NO。 // Problem: A. Distinct Buttons // Contest: Codeforces - Pinely Round 3 (Div. 1 Div. 2) // URL: https…

【docker笔记】docker理论及安装

前言 本笔记来源于尚硅谷docker教学视频 视频地址&#xff1a;https://www.bilibili.com/video/BV1gr4y1U7CY/?spm_id_from333.337.search-card.all.click 纯手打笔记&#xff0c;来之不易&#xff0c;感谢支持~ Docker简介 docker为什么会出现 想象一下&#xff1a;一个应用…

Python遥感影像深度学习指南(1)-使用卷积神经网络(CNN、U-Net)和 FastAI进行简单云层检测

【遥感影像深度学习】系列的第一章,Python遥感影像深度学习的入门课程,介绍如何使用卷积神经网络(CNN)从卫星图像中分割云层 1、数据集 在本项目中,我们将使用 Kaggle 提供的 38-Cloud Segmentation in Satellite Images数据集。 该数据集由裁剪成 384x384 (适用…

第1课 配置FFmpeg+OpenCV开发环境

一、配置开发环境 1.下载FFmpegOpenCV开发所用的SDK压缩包&#xff0c;并解压到E:\SDK下&#xff0c;解压后的路径应为&#xff1a;E:\SDK\ffmpeg-sdk\58\x86\dll及E:\SDK\opencv-sdk\340\x86\dll。 2.新建VC项目&#xff0c;名称为demo1&#xff0c;项目类弄为MFC应用程序&a…

CentOS中docker安装及镜像源配置

1、首先配置docker的阿里yum源 cat >/etc/yum.repos.d/docker.repo<<EOF [docker-ce-edge] nameDocker CE Edge - \$basearch baseurlhttps://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/edge enabled1 gpgcheck1 gpgkeyhttps://mirrors.aliyun.com/do…

第26关 K8s日志收集揭秘:利用Log-pilot收集POD内业务日志文件

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。 OK&#xff0c;到目前为止&#xff0c;我们的服务顺利容器化并上了K8s&#xff0c;同时也能通过外部网络进行请求访问&#xff0c;相关的服务数据也能进行持久化存储了&#xff0c;那么接下来…

【新版】软考 - 系统架构设计师(总结笔记)

个人总结学习笔记&#xff0c;仅供参考&#xff01;&#xff01;&#xff01;! →点击 笔者主页&#xff0c;欢迎关注哦&#xff08;互相学习&#xff0c;共同成长&#xff09; 笔记目录 &#x1f4e2;【系统架构设计系列】系统架构设计专业技能 计算机组成与结构操作系统信…

【PostgreSQL】从零开始:(二十五)数据类型-比特类型

比特类型 比特类型是计算机中存储和处理数据的基本单位&#xff0c;它表示计算机中最小的可寻址的存储单元。一个比特只能表示0或1&#xff0c;可以用来表示二进制数。多个比特可以组合成更复杂的数据类型&#xff0c;例如字节&#xff08;byte&#xff09;、字&#xff08;wo…

MATLAB - 四元数(quaternion)

系列文章目录 前言 一、简介 四元数是一种四元超复数&#xff0c;用于三维旋转和定向。 四元数的表示形式为 abicjdk&#xff0c;其中 a、b、c 和 d 为实数&#xff0c;i、j 和 k 为基元&#xff0c;满足等式&#xff1a;i2 j2 k2 ijk -1。 四元数集用 H 表示&#xff0c…

【Unity 摄像机组件】Camera场景摄像机的认识

OK 同学们好,本节课我们开始学习摄像机创建以及摄像机的属性。 CH3.3 PPT02摄像机相机是玩家用来观看游戏场景世界的基本设备,当游戏运行的时候,游戏画面就是摄像机看到的画面。 PPT3一个场景中可以有无数个摄像机,最终游戏运行的画面可能是很多个摄像机拼凑而成。每个相…

Flink面试题与详解

Flink面试题目合集 从牛客网上找到的一些面试题&#xff0c;如果还有其他的&#xff0c;欢迎大家补充。 1、能否详细描述下Apache Flink的架构组件和其工作原理&#xff1f;请介绍一下Flink on YARN部署模式的工作原理。 官网图&#xff1a; 由两个部分组成&#xff0c;JM&am…

将PPT的图保持高分辨率导入到Word / WPS中

1、将PPT中画好的图组合在一起&#xff0c;选择组合后的图复制&#xff08;Ctrlc&#xff09; 2、在Word中&#xff0c;选中左上角的粘贴选项--->选择性粘贴 WPS选择元文件 / Word选择增强型图元文件 这样放大也不模糊了

new File 得到的是父工程的src路径,而不是本微服务的路径。如何进行全局配置来解决这个问题

如果您希望在微服务中得到本微服务的路径&#xff0c;并进行全局配置来解决这个问题&#xff0c;可以考虑以下两种方法&#xff1a; 使用类加载器获取本微服务的路径&#xff1a; String basePath YourClassName.class.getProtectionDomain().getCodeSource().getLocation().g…

AI智能体的介绍

最近几个月 随着大语言模型的持续火爆 利用大模型来构建AI智能体的研究呢 也陆续进入了人们的视野 AI智能体这个概念呢 也逐渐的流行开来 先是斯坦福大学谷歌的研究者们 成功的构建了一个虚拟小镇 小镇上的居民呢不再是人 而是25个AI的智能体 他们的行为呢 比人类角…

可重复读解决了哪些问题? 对 SQL 慢查询会考虑哪些优化 ?

文章目录 可重复读解决了哪些问题&#xff1f;对 SQL 慢查询会考虑哪些优化 &#xff1f; 可重复读解决了哪些问题&#xff1f; &#xff08;1&#xff09;可重复读的核心就是一致性读(consistent read);保证多次读取同一个数据时&#xff0c;其值都和事务开始时候的内容是一致…

AUTOSAR从入门到精通-存储配置(NvM)(七)

目录 几个相关概念 知识储备 AUTOSAR存储服务 Fee换页机制 换页机制(Bank Swap)

提前预测刚体移动轨迹 预测运动轨迹

提前预测刚体移动轨迹 预测运动轨迹 一、效果二、介绍三、脚本RigidbodyExtension.cs 计算工具类DrawLine.cs 画线工具类 四、资源分享 一、效果 二、介绍 通过计算Unity物理系统的运动方位来判断下一步移动的位置&#xff0c;主要用于物体运动的提前预测&#xff0c;通常使用…

华为vrrp+mstp+ospf+dhcp+dhcp relay配置案例

1、左边是vlan 10主桥&#xff0c;右边是vlan 20的主桥&#xff0c;并且互为备桥 2、 vlan 10 vrrp网关默认用左边&#xff0c;vlan 20的vrrp 网关默认用右边&#xff0c;对应mstp生成树 3、两边都track检测&#xff0c;不通就把vrrp减掉60&#xff0c;这样就会自动切另一边了 …

Hadoop入门学习笔记——七、Hive语法

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 七、Hive语法7.1. 数据库相关操作7.1.1. 创建数据库7.1.2…

kubernetes集群 应用实践 zookeeper部署

kubernetes集群 应用实践 zookeeper部署 零、环境说明 一、zookeeper持久存储准备 zookeeper属于有状态应用&#xff0c;需要为zookeeper部署后端存储服务。 1.1 在NFS服务器添加一块硬盘vdc [rootnfsserver ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT …