Go语言中的Panic和高阶Func详细教程案例

目录标题

  • 一、Panic
    • 1. What is Panic?
    • 2. What should panic be used?
    • 3. Example
    • 4. Defer Calls During a Panic 延迟panic
    • 5. Recovering from a Panic 关联
    • 6. Getting Stack Trace after Recover 输出堆栈信息
    • 7. Panic, Recover and Goroutines
  • 二、First Class Functions
    • 1. What are first class functions?
    • 2. Anonymous functions 匿名函数
    • 3. User defined function types 自定义类型
    • 4. Passing functions as arguments to other functions 将函数作为参数传递给其他函数
    • 5. Returning functions from other functions 从其他函数返回函数
    • 6. Closures闭包函数
    • 7. Practical use of first class functions

一、Panic

1. What is Panic?

	What is Panic?The idiomatic way of handling abnormal conditions in a Go program is using errors.  Errors are sufficient for most of the abnormal conditions arising in the program.But there are some situations where the program cannot continue execution after an abnormal condition.  In this case, we use panic to prematurely terminate the program.  When a function encounters a panic, its execution is stopped, any deferred functions are executed and then the control returns to its caller.  This process continues until all the functions of the current goroutine have returned at which point the program prints the panic message, followed by the stack trace and then terminates.  This concept will be more clear when we write an example program.It is possible to regain control of a panicking program using recover which we will discuss later in this tutorial.panic and recover can be considered similar to try-catch-finally idiom in other languages such as Java except that they are rarely used in Go.什么是Panic?在Go程序中处理异常情况的惯用方法是使用错误。对于程序中出现的大多数异常情况,错误是足够的。但是在某些情况下,程序在出现异常情况后无法继续执行。在这种情况下,我们使用panic来提前终止程序。当一个函数遇到紧急情况时,它的执行将被停止,所有延迟的函数将被执行,然后控制权将返回给它的调用者。这个过程一直持续到当前程序的所有函数都返回为止,此时程序打印panic消息,后跟堆栈跟踪,然后终止。当我们编写示例程序时,这个概念将更加清晰。使用recover可以重新控制错误程序,我们将在本教程后面讨论。panicrecover可以被认为类似于其他语言(如Java)中的try-catch-finally习语,只是它们在Go中很少使用。

2. What should panic be used?

	When Should Panic Be Used?One important factor is that you should avoid panic and recover and use errors where ever possible.  Only in cases where the program just cannot continue execution should panic and recover mechanism be used.There are two valid use cases for panic.An unrecoverable error where the program cannot simply continue its execution.One example is a web server that fails to bind to the required port.  In this case, it's reasonable to panic as there is nothing else to do if the port binding itself fails.A programmer error.Let's say we have a method that accepts a pointer as a parameter and someone calls this method using a nil argument.  In this case, we can panic as it's a programmer error to call a method with nil argument which was expecting a valid pointer.什么时候应该使用Panic?一个重要的因素是,您应该避免错误,尽可能恢复和使用错误。只有在程序无法继续执行的情况下,才应该使用panic和recovery机制。恐慌有两个有效的用例。1. 程序无法继续执行的不可恢复的错误。一个例子是web服务器无法绑定到所需的端口。在这种情况下,Panic是合理的,因为如果端口绑定本身失败,就没有别的办法了。2. 程序员错误。假设我们有一个方法接受一个指针作为参数有人用nil参数调用这个方法。在这种情况下,我们可以panic,因为这是一个程序员的错误,调用nil参数的方法,期望一个有效的指针。

3. Example

        package mainimport ("fmt")func fullName(firstName *string, lastName *string) {if firstName == nil {panic("runtime error: first name cannot be nil")}if lastName == nil {panic("runtime error: last name cannot be nil")}fmt.Printf("%s %s\n", *firstName, *lastName)fmt.Println("returned normally from fullName")}func main() {firstName := "Elon"fullName(&firstName, nil)fmt.Println("returned normally from main")}// panic: runtime error: last name cannot be nil// goroutine 1 [running]:// main.fullName(0xc000062000?, 0xc0000c9f70?)//         D:/Go/oop/Panic.go:12 +0x114// main.main()//         D:/Go/oop/Panic.go:20 +0x35

4. Defer Calls During a Panic 延迟panic

        package mainimport (  "fmt")func fullName(firstName *string, lastName *string) {  defer fmt.Println("deferred call in fullName")		// 当defer遇见panic会先执行堆栈里面的所有defer再执行panicif firstName == nil {panic("runtime error: first name cannot be nil")		// 注意这是panic 不是println}if lastName == nil {panic("runtime error: last name cannot be nil")}fmt.Printf("%s %s\n", *firstName, *lastName)fmt.Println("returned normally from fullName")}func main() {  defer fmt.Println("deferred call in main")firstName := "Elon"fullName(&firstName, nil)fmt.Println("returned normally from main")}// deferred call in fullName  // ddeferred call in main  // dpanic: runtime error: last name cannot be nil// dgoroutine 1 [running]:  // dmain.fullName(0xc00006af28, 0x0)  // d    /tmp/sandbox451943841/prog.go:13 +0x23f// dmain.main()  // d    /tmp/sandbox451943841/prog.go:22 +0xc6

5. Recovering from a Panic 关联

        package mainimport (  "fmt")func recoverFullName() {  if r := recover(); r!= nil {		// 当前recover接受panic的错误信息fmt.Println("recovered from ", r)}}func fullName(firstName *string, lastName *string) {  defer recoverFullName()if firstName == nil {panic("runtime error: first name cannot be nil")}if lastName == nil {panic("runtime error: last name cannot be nil")}fmt.Printf("%s %s\n", *firstName, *lastName)fmt.Println("returned normally from fullName")}func main() {  defer fmt.Println("deferred call in main")firstName := "Elon"fullName(&firstName, nil)fmt.Println("returned normally from main")}// recovered from  runtime error: last name cannot be nil  // returned normally from main  // deferred call in main  // Example 2package mainimport (  "fmt")func recoverInvalidAccess() {  if r := recover(); r != nil {		// recover接收错误信息fmt.Println("Recovered", r)		}}func invalidSliceAccess() {  defer recoverInvalidAccess()n := []int{5, 7, 4}fmt.Println(n[4])		// 运行至此 发生错误 执行panic 执行defer fmt.Println("normally returned from a")}func main() {  invalidSliceAccess()fmt.Println("normally returned from main")}// Recovered runtime error: index out of range [4] with length 3  // normally returned from main  

6. Getting Stack Trace after Recover 输出堆栈信息

        package mainimport (  "fmt""runtime/debug")func recoverFullName() {  if r := recover(); r != nil {		// 接受错误panic信息fmt.Println("recovered from ", r)debug.PrintStack()				// debug.PrintStack()函数用于打印当前的堆栈跟踪信息 }								  // 用于在程序出现错误时输出堆栈跟踪,以帮助调试错误。}func fullName(firstName *string, lastName *string) {  defer recoverFullName()if firstName == nil {panic("runtime error: first name cannot be nil")}if lastName == nil {panic("runtime error: last name cannot be nil")}fmt.Printf("%s %s\n", *firstName, *lastName)fmt.Println("returned normally from fullName")}func main() {  defer fmt.Println("deferred call in main")firstName := "Elon"fullName(&firstName, nil)fmt.Println("returned normally from main")}// recovered from  runtime error: last name cannot be nil  // goroutine 1 [running]:  // runtime/debug.Stack(0x37, 0x0, 0x0)  //     /usr/local/go-faketime/src/runtime/debug/stack.go:24 +0x9d// runtime/debug.PrintStack()  //     /usr/local/go-faketime/src/runtime/debug/stack.go:16 +0x22// main.recoverFullName()  //    /tmp/sandbox771195810/prog.go:11 +0xb4// panic(0x4a1b60, 0x4dc300)  //     /usr/local/go-faketime/src/runtime/panic.go:969 +0x166// main.fullName(0xc0000a2f28, 0x0)  //     /tmp/sandbox771195810/prog.go:21 +0x1cb// main.main()  //     /tmp/sandbox771195810/prog.go:30 +0xc6// returned normally from main  // deferred call in main  

7. Panic, Recover and Goroutines

        package mainimport (  "fmt")func recovery() {  if r := recover(); r != nil {fmt.Println("recovered:", r)}}func sum(a int, b int) {  defer recovery()fmt.Printf("%d + %d = %d\n", a, b, a+b)done := make(chan bool)go divide(a, b, done)		// 开启一个新的线程 <-done}func divide(a int, b int, done chan bool) {  fmt.Printf("%d / %d = %d", a, b, a/b)		// 不能除以0 integer divide by zerodone <- true}func main() {  sum(5, 0)	// 遇见错误不在向下执行fmt.Println("normally returned from main")}// 5 + 0 = 5  // panic: runtime error: integer divide by zero// goroutine 18 [running]:  // main.divide(0x5, 0x0, 0xc0000a2000)  //     /tmp/sandbox877118715/prog.go:22 +0x167// created by main.sum  //     /tmp/sandbox877118715/prog.go:17 +0x1a9

二、First Class Functions

1. What are first class functions?

	A language that supports first class functions allows functions to be assigned to variables, passed as arguments to other functions and returned from other functions. Go has support for first class functions.In this tutorial, we will discuss the syntax and various use cases of first class functions.一种支持第一类函数的语言允许函数被分配给变量,作为参数传递给其他函数,并从其他函数返回。Go支持一级函数。在本教程中,我们将讨论第一类函数的语法和各种用例。

2. Anonymous functions 匿名函数

        package mainimport (  "fmt")func main() {  a := func() {fmt.Println("hello world first class function")}a()fmt.Printf("%T", a)func() {fmt.Println("hello world first class function")}()func(n string) {fmt.Println("Welcome", n)}("Gophers")}// hello world first class function// func()// hello world first class function// Welcome Gophers

3. User defined function types 自定义类型

        package mainimport (  "fmt")type add func(a int, b int) intfunc main() {  var a add = func(a int, b int) int {return a + b}s := a(5, 6)fmt.Println("Sum", s)}// Sum 11

4. Passing functions as arguments to other functions 将函数作为参数传递给其他函数

        package mainimport (  "fmt")func simple(a func(a, b int) int) { // 接受一个名为 a 的参数,这个参数是一个函数类型,该函数接受两个整数参数并返回一个整数。fmt.Println(a(60, 7)) //	在 simple 函数内部,它调用了传递进来的函数 a,并传递了两个整数参数 60 和 7。}func main() {f := func(a, b int) int { //return a + b // 接受两个整数参数并返回它们的和。}simple(f)}// 67

5. Returning functions from other functions 从其他函数返回函数

        package mainimport (  "fmt")func simple() func(a, b int) int {  f := func(a, b int) int {return a + b}return f}func main() {  s := simple()fmt.Println(s(60, 7))}// 67

6. Closures闭包函数

        package mainimport "fmt"func appendStr() func(string) string {t := "hello"c := func(b string) string {t = t + " " + breturn t}return c}func main() {a := appendStr()b := appendStr()fmt.Println(a("world"))fmt.Println(b("everyone"))fmt.Println(a("Gopher")) // 这个时候 已经变成 hello world + Gopherfmt.Println(b("!"))}

7. Practical use of first class functions

        package mainimport (  "fmt")type student struct {  firstName stringlastName  stringgrade     stringcountry   string}func filter(s []student, f func(student) bool) []student {  var r []studentfor _, v := range s {if f(v) == true {r = append(r, v)}}return r}func main() {  s1 := student{firstName: "Naveen",lastName:  "Ramanathan",grade:     "A",country:   "India",}s2 := student{firstName: "Samuel",lastName:  "Johnson",grade:     "B",country:   "USA",}s := []student{s1, s2}f := filter(s, func(s student) bool {if s.grade == "B" {return true}return false})fmt.Println(f)}// [{Samuel Johnson B USA}]

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

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

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

相关文章

【数据库】MySQL基础知识全解

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于拓跋阿秀、小林coding等大佬博客进行的&#xff0c;每个知识点的修…

基于Googlenet深度学习网络的人脸身份识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..................................................................... % 定义修改的范围 …

hive表向es集群同步数据20230830

背景&#xff1a;实际开发中遇到一个需求&#xff0c;就是需要将hive表中的数据同步到es集群中&#xff0c;之前没有做过&#xff0c;查看一些帖子&#xff0c;发现有一种方案挺不错的&#xff0c;记录一下。 我的电脑环境如下 软件名称版本Hadoop3.3.0hive3.1.3jdk1.8Elasti…

Hugging Face 实战系列 总目录

PyTorch 深度学习 开发环境搭建 全教程 Transformer:《Attention is all you need》 Hugging Face简介 1、Hugging Face实战-系列教程1&#xff1a;Tokenizer分词器&#xff08;Transformer工具包/自然语言处理&#xff09; Hungging Face实战-系列教程1&#xff1a;Tokenize…

浅析ARMv8体系结构:异常处理机制

文章目录 概述异常类型中断终止Abort复位Reset系统调用 异常处理流程异常入口异常返回异常返回地址 堆栈选择 异常向量表异常向量表的配置 同步异常解析相关参考 概述 异常处理指的是处理器在运行过程中发生了外部事件&#xff0c;导致处理器需要中断当前执行流程转而去处理异…

代码随想录算法训练营day48 | LeetCode 198. 打家劫舍 213. 打家劫舍 II 337. 打家劫舍 III

198. 打家劫舍&#xff08;题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台&#xff09; 思路&#xff1a;dp题除背包外的另外一类题目&#xff0c;重点不在于看前面的情况&#xff0c;而在于考虑本节点的情况。一种情况&#xf…

leetcode原题: 最小值、最大数字

题目1&#xff1a;最小值 给定两个整数数组a和b&#xff0c;计算具有最小差绝对值的一对数值&#xff08;每个数组中取一个值&#xff09;&#xff0c;并返回该对数值的差 示例&#xff1a; 输入&#xff1a;{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8} 输出&#xff1a;3&…

【德哥说库系列】-ASM管理Oracle 19C单实例部署

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

一百六十九、Hadoop——Hadoop退出NameNode安全模式与查看磁盘空间详情(踩坑,附截图)

一、目的 在海豚跑定时跑kettle的从Kafka到HDFS的任务时&#xff0c;由于Linux服务器的某个文件磁盘空间满了&#xff0c;导致Hadoop的NodeName进入安全模式&#xff0c;此时光执行hdfs dfsadmin -safemode leave命令语句没有效果&#xff08;虽然显示Safe mode is OFF&#x…

Day53|leetcode 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

leetcode 1143.最长公共子序列 题目链接&#xff1a;1143. 最长公共子序列 - 力扣&#xff08;LeetCode&#xff09; 视频链接&#xff1a;动态规划子序列问题经典题目 | LeetCode&#xff1a;1143.最长公共子序列_哔哩哔哩_bilibili 题目概述 给定两个字符串 text1 和 text2&…

Django请求的生命周期

Django请求的生命周期是指: 当用户在浏览器上输入URL到用户看到网页的这个时间段内&#xff0c;Django后台所发生的事情。 直白的来说就是当请求来的时候和请求走的阶段中&#xff0c;Django的执行轨迹。 一个完整的Django生命周期: 用户从客户端发出一条请求以后&#xff…

uniapp qiun charts H5使用echarts的eopts配置不生效

原因是&#xff1a;使用web的要设置 echartsH5 :echartsH5"true" <template><view class"charts-box"><view class"chart-title"> 趋势</view><qiun-data-chartstype"column":eopts"eopts":cha…

网络编程day2——基于TCP/IP协议的网络通信

TCP网络通信编程模型&#xff1a; 计算机S 计算机C 创建socket对象 创建socket对象 准备通信地址(自己的ip(非公网ip)) 准备通信地址 (计算机S的&#xff0c;与C在同一个局域网&#…

图像库 PIL(一)

Python 提供了 PIL&#xff08;python image library&#xff09;图像库&#xff0c;来满足开发者处理图像的功能&#xff0c;该库提供了广泛的文件格式支持&#xff0c;包括常见的 JPEG、PNG、GIF 等&#xff0c;它提供了图像创建、图像显示、图像处理等功能。 基本概念 要学…

C++类模板

这是一个简单的C程序&#xff0c;展示了如何使用Stack类模板来操作int和string类型的栈。 首先&#xff0c;我们定义了两个栈&#xff1a;一个用于int类型&#xff0c;另一个用于string类型。然后&#xff0c;我们使用push()方法将元素压入相应的栈中&#xff0c;并使用top()方…

延迟队列的理解与使用

目录 一、场景引入 二、延迟队列的三种场景 1、死信队列TTL对队列进行延迟 2、创建通用延时消息死信队列 对消息延迟 3、使用rabbitmq的延时队列插件 x-delayed-message使用 父pom文件 pom文件 配置文件 config 生产者 消费者 结果 一、场景引入 我们知道可以通过TT…

Mybatis学习|多对一、一对多

有多个学生&#xff0c;没个学生都对应&#xff08;关联&#xff09;了一个老师&#xff0c;这叫&#xff08;多对一&#xff09; 对于每个老师而言&#xff0c;每个老师都有N个学生&#xff08;学生集合&#xff09;&#xff0c;这叫&#xff08;一对多&#xff09; 测试环境…

[杂谈]-快速了解Modbus协议

快速了解Modbus协议 文章目录 快速了解Modbus协议1、为何 Modbus 如此受欢迎2、范围和数据速率3、逻辑电平4、层数5、网络与通讯6、数据帧格式7、数据类型8、服务器如何存储数据9、总结 ​ Modbus 是一种流行的低速串行通信协议&#xff0c;广泛应用于自动化行业。 该协议由 Mo…

力扣2. 两数相加

2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个…

16 个前端安全知识

16 个前端安全知识 去年 security course 上的是 React&#xff0c;然后学了一些 一些 React 项目中可能存在的安全隐患&#xff0c;今年看了一下列表&#xff0c;正好看到了前端也有更新&#xff0c;所以就把这个补上了。 一个非常好学习各种安全隐患的机构是 https://owasp…