golang中的defer-recover-panic

panic

panic其实就是我们其他语言中的throw exception

recover

recover其实就是其他语言的try catch

注意

  1. recover如果想起作用的话, 必须在defered函数中使用。
  2. 在正常函数执行过程中,调用recover没有任何作用, 他会返回nil。如这样:fmt.Println(recover()) 。
  3. 如果当前的goroutine panic了,那么recover将会捕获这个panic的值,并且让程序正常执行下去。不会让程序crash。

总结

总结

  1. 先执行return再执行defer
  2. 如果触发多个panic,后触发的Panic会覆盖前面的Panic
  3. defer-recover必须写在panic前面,因为发生panic后将不会执行位于panic后面的代码,如果在Panic之前有的defer代码将会按序执行
  4. 如果当前函数触发了panic之后没有进行defer-recover,此时这个panic(会带着自己的异常去找对应的defer-recover)将会传回到上一级,如果上一级的defer链也没有对应的defer-recover将会一直返回到main,造成整个程序crash。如果不想影响函数的主流程,需要在对应的函数panic前面加上defer-recover
  5. 协程遇到panic之后,将会遍历本协程的defer链表,并执行对应的defer,执行defer过程中,遇到recover就停止panic,返回recover处继续执行,如果没有遇到recover,遍历完本协程的defer链表,(将会沿着调用链返回上一级继续执行上一级的defer链表直到异常捕获或到main之后crash)或者如果没有上一级就会抛出错误信息,
go

golang中的iota

note info 经常有面试官甩出个const以及iota的面试题

如下便是国内某公司的面试题:

回答输出结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import "fmt"

/**
* @Author: yirufeng
* @Email: yirufeng@foxmail.com
* @Date: 2020/10/13 6:06 下午
* @Desc:
*/


//第一个const来自于面试题
const (
i = 7
j
k
)

const (
a = 7
b
c = 3
m = 1 << iota
n
o
)

func main() {
fmt.Println(a, b, c)
fmt.Println(i, j, k, m, n, o)
}

总结

进行几点总结

  1. 不同 const 定义块互不干扰:即我们在推算这些常量值的时候只需要看当前的 const ( ) 之内的内容,不用关心之前或之后是否也用常量定义语句
  2. 所有注释行和空行全部忽略:
    1. 注意:_ 并不是一个空行,它是一个省略了标识符也省略了表达式的常量定义,这一点你需要清楚,不要大意。
  3. 没有表达式的常量定义复用上一行的表达式:例如如下的代码,j中没有写表达式,那么j是复用上一行表达式的即j = iota,但此时iota的值会为2
    1
    2
    3
    4
    const (
    i = iota
    j
    )
  4. 从第一行开始,iota 从 0 逐行加一:也就是说赋值表达式里无论是否引用了 iota,也无论引用了多少次,iota 的都会从常量定义块的第一行(注意这里不计空行和注释)开始计数,从 0 开始,逐行加一,例如上面代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     const (
    i = 7 //iota = 1
    j //iota = 2
    k //iota = 3
    )

    const (
    a = 7 //iota = 1
    b //iota = 2
    c = 3 //iota = 3
    m = 1 << iota //iota = 4
    n //iota = 5
    o //iota = 6
    )
  5. 替换所有 iota:直接将表达式中的iota全部替换为我们上一步写出的值即可
go

golang中命令行参数的使用

使用os.Args获取输入的命令行参数

os.Args获取输入的命令行参数

  1. os.Args本质上是一个切片,会将命令行的内容全部读取,只是将我们输入的内容按照空格进行分割,其中第1个是执行的程序的全路径名称,
  2. 后面的为我们执行的时候命令行上的其他参数

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"os"
)

/**
* @Author: yirufeng
* @Email: yirufeng@foxmail.com
* @Date: 2020/10/6 6:00 下午
* @Desc: os.Args练习


本质上是一个切片,会将命令行的内容全部读取,只是将我们输入的内容按照空格进行分割,其中第1个是程序执行的名称,
后面的为我们执行的时候命令行上的其他参数
*/
func main() {
fmt.Println(len(os.Args))
fmt.Println(os.Args)
}

使用flag包来解析命令行参数

具体步骤

  1. StringVar,IntVar,BoolVar需要传入4个参数
    1. 第1个参数为接收值的变量的地址
    2. 第2个参数为我们使用命令行中的-后面紧跟的字符作为key
    3. 第3个参数为默认值
    4. 第4个参数为参数说明(命令设置错误时的说明)
  2. 使用flag包解析命令行参数最后一定要记得flag.Parse()之后,我们上面的设置的解析参数才会生效

到时候执行如下代码的时候,我们需要先使用go build指令进行编译,编译之后运行可执行文件的时候后面还得加上参数,这里我们应该加上./demo -h 10.26.166.14 -p 3309 -o false 如果不指定参数的时候我们将会使用程序中设置的默认值来读取

go

golang中关于文件的操作

终端读写操作note info 默认主题色,适合中性的信息 终端读写相关的文件句柄常量os.Stdin 标准输入os.Stdout 标准输出os.Stderr 标准错误以上3个都是以文件的形式存在 查看代码测试 note info 默认主题色,适合中性的信息 标题...
go

Golang中的错误处理

自定义错误

  1. 因为error是一个接口,因此我们可以自定义一个error
  2. 实际开发中我们要判断错误的类型,直接进行类型断言(也可以通过switch进行类型断言分支)

三部曲自定义一个错误

  1. 自定义一个错误结构体
  2. 实现我们的Error方法
  3. 返回错误的时候直接返回一个&我们自己的错误

注意:我们最常用的就是errors.New(字符串)

Golang的序列化

  1. Go中使用encoding/json中的Marshal以及Unmarshal对数据进行序列化和反序列化
  2. json中的key永远为字符串,Golang中一般我们键都为string,value为interface,之后拿到interface采用反射来判断类型,
  3. 序列化的时候首字母必须大写,不然访问不到
  4. 如果希望序列化之后结构体的key有其他别名或者首字母小写,可以加上一个tag

具体的序列化

  1. map序列化之后,Key为json中的key,value也是json中的value
  2. 结构体序列化之后,如果有tag,那么key就是对应的tag

注意:使用Unmarshal()的时候,第2个参数,直接传声明的变量进去即可,因为Golang会自动帮我们分配内存和赋值
例如传入一个只声明的map或结构体

gojson

爬取豆瓣Top250电影

前言

十一无聊,想着看几部电影来happy一下,不知道有什么精彩电影,于是就爬取一下豆瓣的Top250

项目已经开源到了网站

实现步骤

  1. 爬取页面内容(伪装一个user-agent)
  2. 获取页面内容后使用正则表达式提取自己想要的内容(正则表达式编写)
  3. 将自己提取到的内容存放到数据库中(go的数据持久化)