2021/9/5 老男孩带你21周搞定Go语言 (五)

P75 今日内容

在这里插入图片描述

P76内容回顾

一个文件夹就是一个包,包里都是.go文件。
包导入的时候可以起别名,可以匿名导入包。
包里面的标识符,需要首字母大写,才被外部可见,可以调用

在这里插入图片描述

包导入的路径,是从$GOpath的src后面的路径开始写起

在这里插入图片描述
init是包导入的时候会自动执行,一个包里只有一个init,init没有参数也没有返回值,也不能手动调用,一般用于初始化操作,一般初始化配置文件,数据库链接等。
在这里插入图片描述
在这里插入图片描述
**接口是一种特殊类型,是你要实现的方法的清单。
实现了接口的方法就实现了这个接口,就可以作为这个接口类型的变量。
**
在这里插入图片描述
空接口,代表了一个接口里没有方法清单,一个方法都没有,那么所有类型都实现了一个空接口,可以把任何类型存到空接口里,interFace{}表示一个空接口。
一般作为函数参数,fmt.println就是 一个空接口 ,或者map里想存任意类型的值可以用空接口

在这里插入图片描述
接口底层其实分两部分,一个 动态类型,一个动态值,类型断言就是判断类型是什么类型的。前提是判断的类型是个接口类型的变量。
T大t一般在go语言里代表type。
interface{}就代表一个空接口。

在这里插入图片描述
有多个判断,可以使用switch,现在只能猜,用了反射才能知道确切的类型
在这里插入图片描述
在这里插入图片描述
文件操作,打开关闭,读写,程序也是通过系统调用去操作文件,如果不释放io,就会让操作系统资源耗尽。正常大公司服务器都是3年报废,或者退居2线,重要的生产三天两头出问题,谁也受不了了。

在这里插入图片描述
打开一个问获得文件对象,如果错误返回错误码,判断错误的时候不为空,就一定有错误

在这里插入图片描述
要用下面的方式写,go语言可以有多个返回值,如果f1上面的错误了,那么fileobj就是nil,nil就没有close方法,就返回给你一个空指针引用
在这里插入图片描述
读文件三种方法,bufio会有一个中间状态,缓冲区,读到缓冲区,达到缓冲区的阈值就返回到代码。写的时候缓冲区调用flush才能写,但是中间断电,数据就丢了
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

P77 在文件中间插入内容

在这里插入图片描述
所有文件相关的操作都可以在标准库里查找。

在这里插入图片描述
在这里插入图片描述
seek(1,0)1个字节,从0开始,读一个切片
在这里插入图片描述
windows这里有/r/n

在这里插入图片描述
所以 需要移动三个字符,光标移动到b,3代表移动三个位置,0代表从什么地方开始
在这里插入图片描述
像这样不换行就会读到b了

在这里插入图片描述
往文件里写,需要额外声明一个切片,拿到上面读到的切片。
切片初始化只能用make,不能用new

在这里插入图片描述
这样就相当于往文件写了C
在这里插入图片描述
相当于把原来的b覆盖了

在这里插入图片描述
插入数据的话,只能先新建一个文件,读出来,再出入到新的文件里,所有语言都不可能读一个文件,从中间插入数据。
在这里插入图片描述
读文件写入临时文件,再写入要插入的内容,
在这里插入图片描述
紧接着把源文件后续的内容写入临时文件
在这里插入图片描述
在这里插入图片描述

P78 time包

在这里插入图片描述
time.Time代表时间类型

在这里插入图片描述
在这里插入图片描述时间戳是从1970年1月1日8点,到当前的总毫秒数

在这里插入图片描述
获取时间戳,nano纳秒
在这里插入图片描述
在这里插入图片描述
时间戳转换成时间格式
在这里插入图片描述
在这里插入图片描述
时间间隔

在这里插入图片描述
时间操作+

在这里插入图片描述
明天的时间
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
时间就一秒钟 给一个值
在这里插入图片描述
在这里插入图片描述
go的时间 格式化模板是它的诞生时间 ,2006年1月2日15点04分,也就是 2006 1 2 3 4

在这里插入图片描述
转换成字符串类型的时间,格式化
![zhuanzhuan![](https://img-blog.csdnimg.cn/76be4b8dc3024fccb2637f1f5c027f30.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBANDhONkU=,size_20,color_FFFFFF,t_70,g_se,x_16)
想要格式是2006/01/02 11:11:11
在这里插入图片描述
加上上午下午
在这里插入图片描述
加上毫秒
在这里插入图片描述
字符串类型转换成时间戳
在这里插入图片描述

P79 time包补充

但凡调用其他包里的东西,首字母都需要大写,小写调用不到

在这里插入图片描述
相差3600多个小时
在这里插入图片描述
在这里插入图片描述
可以试试UTC时间
在这里插入图片描述
减的是一个时间对象,返回值是个 时间间隔,

在这里插入图片描述
指定时区
在这里插入图片描述
sleep,函数名(参数)没有返回值,参数是一个时间间隔的类型

在这里插入图片描述
**duration是一个基于int64的类型,定义了两个常量,只能在time包里使用,需要判断传进来的参数是否符合要求,最大值最小值
**

在这里插入图片描述
这样赋值了传进去就不匹配了,类型不能转换

在这里插入图片描述
需要显示转换类型

在这里插入图片描述
在这里插入图片描述

P80 日志库需求分析

先看一下时区的问题,默认是获取的本地的时间
在这里插入图片描述
明天的当前时间,按照东八区的时区和格式去解析一个字符串的时间。time.loadlocation根据字符串加载时区
在这里插入图片描述
按照指定时区解析时间parseinlocation,这样就获得了正确的东八区相减
在这里插入图片描述
在这里插入图片描述

P81 日志库简单实现

go语言的日志可以相对比较简单

在这里插入图片描述
打印的时候会在前面加默认的时间戳

在这里插入图片描述
在这里插入图片描述
打开一个文件,把日志输出到文件

在这里插入图片描述
在这里插入图片描述
日志库的需求:
1支持往不同的地方输出日志
2日志级别:debug,info,warning,error,fatal严重错误
3.日志支持开关
4.日志要有基本格式,时间,行号,文件名,级别,日志信息
5.日志文件要切割

在这里插入图片描述
需要自己写的程序调用自己写的日志库
在这里插入图片描述
日志库开发,fprint是往文件里去写
在这里插入图片描述
大概的架子
在这里插入图片描述
写一个for循环调用
在这里插入图片描述
这些只是最简单的实现,离需求还差点

在这里插入图片描述
添加时间格式,并换行
在这里插入图片描述
在这里插入图片描述
再把日志级别加上去
在这里插入图片描述
a
日志开关,比如开发的时候什么级别都可以输出 ,上线之后只有INFO级别输出

在这里插入图片描述
基于内置的int16类型造了一个自己的类型level。iota第一个是0,每一行加1
在这里插入图片描述
需要实现一个方法,获得字符串的级别,解析成内置类型的级别,parseloglevel
在这里插入图片描述
如果传的类型什么都不是,可以返回一个unknown,错误
在这里插入图片描述
error.mew造一个新的错误
在这里插入图片描述errors

在这里插入图片描述
用户传进来字符串的时候,需要解析。
构造一个logger对象,里面有一个日志级别

在这里插入图片描述
如果上线就判断只输出info级别的日志
在这里插入图片描述
每个函数都进行调用
在这里插入图片描述
如果是debug级别,相当于其他任何级别都可以输出,所以是>=
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

P82 runtime.caller

可以添加一个行号,runtime是一个进行时,go自带gc,caller,传一个int参数,就可以拿到一个当前程序的隔了对应多少层,如果ok是true就可以拿到,如果是false,就拿不到。pc可以拿到函数的一些信息,file是当前执行的哪个文件,line是第几行
在这里插入图片描述
main函数直接调用,所以直接传入0.
main函数是程序的入口函数,需要传其他数了,默认就是0

在这里插入图片描述
调用文件的全部路径。行数11


假如把这段代码封装到函数里,在main函数里调用,就隔了一层,打印的行号一定是执行runtime.caller的行号
在这里插入图片描述
想要获取21行,这一行调用,就等于再往上找一层,就是21行
在这里插入图片描述
那么再往上调用,再找一层就是25行了
在这里插入图片描述
拿到函数名,pc
在这里插入图片描述
拿到最终的f函数,写个0即可
在这里插入图片描述
这样就拿到f1
在这里插入图片描述
拿到文件名
在这里插入图片描述
在外部进行调用
在这里插入图片描述

在记录日志的地方进行调用
在这里插入图片描述
但是一个个 添加太麻烦,可以写到一个log函数里
在这里插入图片描述
在这里插入图片描述
再写一个把日志级别进行转换的函数getLogString
在这里插入图片描述

在这里插入图片描述
现在调用就有行号了
在这里插入图片描述
函数名 可以做一下分割
在这里插入图片描述

P83 记录日志时支持格式化输出

导入自己开发的包并进行调用
在这里插入图片描述
谁调用就记录这个是谁调用的信息
在这里插入图片描述
可以加一个格式参数,后面可以传任何类型的参数等于是传的信息,和a是一个格式化的关系

在这里插入图片描述
在这里插入图片描述

可以往里面传字符串的格式化,可以传任意格式的进去

在这里插入图片描述

P84 实现往文件里记录日志

改个名字,区分一下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
把日志存到文件里

在这里插入图片描述
newfiledlogger构造函数
在这里插入图片描述

把级别复制过来

在这里插入图片描述可以加个参数,输出的地方不同
在这里插入图片描述
都替换一下
在这里插入图片描述
在这里插入图片描述
这样判断就可以移到一个函数里了,直接打印就行

在这里插入图片描述
这样就更简单了

在这里插入图片描述

文件版的enable
在这里插入图片描述
但是肯定要一开始打开文件就初始化好
在这里插入图片描述
按照文件路径和文件名将文件打开,写日志都是追加,没有就创建,这样返回一个文件对象。
如果打开文件失败了就记录一下。

在这里插入图片描述
日志文件打不开就没必要往下走了,还有一个专门输出error日志的文件
在这里插入图片描述
关闭文件
在这里插入图片描述
往文件里去记录
在这里插入图片描述
如果要记录的日志等级大于等于error,还要在error日志文件中再记录一份

在这里插入图片描述
在这里插入图片描述
传入参数
在这里插入图片描述
现在就有日志了
在这里插入图片描述

P85 日志文件切割

可以按文件大小切割,和按日期切割

在这里插入图片描述
判断传入的文件是否是err,返回os.file结构体的指针

在这里插入图片描述
原始包里提供的时一个接口类型,里面有一些方法,返回值
在这里插入图片描述
获取文件对象的详细信息
在这里插入图片描述
上面的代码移到之前的代码里,获取传进来的文件大小,当前文件大小大于等于日志文件最大值就返回true
在这里插入图片描述
在下面调用checksize。
进行日志切割
1.关闭当前日志文件
2.备份一下 rename
3.打开一个新的日志文件
4.将打开的新日志文件对象赋值给f.fileobj

在这里插入图片描述
重命名后,打开一个新的日志文件,往里面继续写日志

在这里插入图片描述

下面记录错误日志的就也需要,把切割的代码部分抽出去变成一个函数

在这里插入图片描述
这里其实可以打印文件名
在这里插入图片描述
还需要判断切的时info日志还是err日志

在这里插入图片描述
返回增加一个nil,split还需要接收对象

在这里插入图片描述
在这里插入图片描述
返回的错误文件对象
在这里插入图片描述

P86 日志库补充

把原来的日志文件先删除
在这里插入图片描述
报错是因为文件关闭了,就代表拿不到文件信息,

在这里插入图片描述
关闭文件放到下面
在这里插入图片描述
备份
在这里插入图片描述
initfile的作用是创建文件实例的时候,需要做一个初始化
在这里插入图片描述
写的这些方法的作用

在这里插入图片描述
在这里插入图片描述
文件日志结构体

在这里插入图片描述
console和记录文件的都需要实现日志界别,也就是可以定义interface接口
在这里插入图片描述
定义接口后,可以定义一个日志实例,在main包里的任何地方去使用,或者其他包里去使用。

定义一个构造函数
在这里插入图片描述
两个都可以赋值
在这里插入图片描述
也可以包装起来,传不同参数时候,可以进行switch
在这里插入图片描述
上面就是申明一个全局的接口变量

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

P87 反射及附加题需求

之前写的类型,在go语言执行的时候就已经知道了是什么类型,反射只有执行到指定的行才知道是什么类型

在这里插入图片描述
反射可以动态获取

在这里插入图片描述
这样是可以传进去的,但是执行会报错
在这里插入图片描述
任何接口值都是由一个具体类型和具体类型的值两部分组成

在这里插入图片描述
也就是动态类型和动态类型的值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就能拿到类型

在这里插入图片描述
类型分为了type和kind,kind对应底层造的类型
在这里插入图片描述
这样就打印出来main.cat
14:07
在这里插入图片描述
类型,种类kind结构体
在这里插入图片描述
可以基于内置的类型造一个自己的类型
在这里插入图片描述
valueof返回一个reflect.value的类型,其中包含原始值信息,和原始值之间可以互相转换。
在这里插入图片描述
这里取到接口传过来的变量,如果种类满足int64,就转换成int64;如果是float32就转成float32
在这里插入图片描述
复制到这里进行测试

在这里插入图片描述
下面拿到的是值的类型

在这里插入图片描述
在这里插入图片描述
通过反射设置变量的值,上面是读变量的值,go语言的函数传值永远是拷贝,但凡修改值的时候,一定要return。
在这里插入图片描述
在这里插入图片描述
想要修改这个100,但是提示需要传一个指针
在这里插入图片描述
传一个指针,但是没有修改成功,函数还需要修改

在这里插入图片描述
在函数里这样使用也就获得了地址

在这里插入图片描述
这样就直接修改了

在这里插入图片描述
isnil判断特定的值是否未null,特有的值必须是通道,函数,接口,指针,映射,切片

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
结构体字段在反射里也有类型structfield

在这里插入图片描述
在这里插入图片描述
学生结构体有名字和分数

在这里插入图片描述
可以返回结构体字段数目

在这里插入图片描述
增加多个值,测试下面获取在这里插入图片描述
在这里插入图片描述
现在就获取到了

在这里插入图片描述反射有好处,有坏处。
好处:让代码更加灵活。
坏处:牺牲了一些代码的性能

在这里插入图片描述
创建一个ini文件
在这里插入图片描述
造一个结构体
在这里插入图片描述
把文件里的值拿出来,这是需要实现的
在这里插入图片描述
可以加上ini解析
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值