2021/8/28 老男孩带你21周搞定Go语言 (四)

P63 今日内容

在这里插入图片描述

P64 初识接口类型

接口是一种类型,结构体也是一种类型,区别其他基本类型,可以展示多维度的数据
在这里插入图片描述
da谁就会speak,但是这样写就限定了dog类型,cat就传不进去了

在这里插入图片描述
go语言里不关心一个变量是什么类型,只关心能调用的它的什么方法
在这里插入图片描述
那这个函数就要限定传进来的类型有speak方法

在这里插入图片描述
接口就是解决这个问题,约束传递进来的变量方法。
像类似的例子在我们编程过程中会经常遇到:
比如一个网上商城可能使用支付宝、微信、银联等方式去在线支付,我们能不能把它们当成支付方式来处理呢?
比如三角形,四边形,圆形都能计算周长和面积,我们能不能把它们当成"图形*来处理呢?
比如销售、行政程序员都船计算月薪,我们能不能把他们当成员工"来处理呢?
Go语言中为了解决类似上面的问题,就设计了接口这个概念。接口区别于我们之前所有的具体类型,接口是一种抽象的类
型。当你看到一个接口类型的值时,你不知道它是什么,唯一知道的是通过它的方法能做什么。

在这里插入图片描述
接口是一种特殊的类型,规定了变量应该有哪些方法
在这里插入图片描述
在这里插入图片描述
如何使用,类型名可以写到参数里,函数里接收一个speaker类型的变量
在这里插入图片描述
cat和dog都有speak方法,都能当作speaker类型的变量,这个speak类型比较特别,只规定了你的结构体和变量有什么方法,必须要有一个speak方法,只要实现了speak方法都是speaker类型
在这里插入图片描述
这样就实现了speaker作为一个特殊的类型,只规定了你要有什么方法,没有speak方法,就不是speaker类型的变量,不能当作参数传进去

在这里插入图片描述
接口只是一种类型,里面是约束别人要实现的什么方法,也叫方法签名,可有多个

在这里插入图片描述
在这里插入图片描述
造一个run方法
在这里插入图片描述
drive函数接收一个car类型的变量,car类型是一个接口类型,不管什么结构体,只要有run方法就能是car类型

在这里插入图片描述
在这里插入图片描述
这种适合在不管后端存储什么,只要提供增删改查接口就行,遇到不同类型有统一方法,就可以使用接口类型

在这里插入图片描述

P65 接口的定义与实现

约束力变量有哪些方法

在这里插入图片描述
定义,只要是类型就用type关键字来定义,用来给变量,参数,返回值等设置类型。
在这里插入图片描述
接口的实现
一个变量如果实现了接口中规定的所有的方法,那么这个变量就实现了这个接口,可以称为这个接口类型的变量。
比如baoshijie可以称为car类型的变量

在这里插入图片描述
speaker能接收cat,dog,因为只要满足了接口类型约束的方法就可以称为接口类型的变量。可以把接口类型当作一个普通的类型来使用

在这里插入图片描述
只要实现了speak的方法,都能满足接口类型
在这里插入图片描述
go语言现在是面向接口的概念,面向对象的概念是属性和数据放在一个类里,在go里引出了一个接口,不关心属性和数据,只要实现了接口就可以。
接口是一种类型,约束规定了你类型需要实现的方法

在这里插入图片描述

再写一个例子,动物接口需要有move和eat方法
在这里插入图片描述
猫也需要实现这样的方法
在这里插入图片描述
这样实现的就不是同一个方法,不满足接口

在这里插入图片描述
这样猫就实现了接口
在这里插入图片描述

动物是一个接口类型,只要实现接口里的所有方法,对应的变量就可以存在animal里
在这里插入图片描述
调用方法

在这里插入图片描述
chicken现在不满足接口条件,不能让接口类型变量接收
在这里插入图片描述
修改eat方法函数
在这里插入图片描述
定义什么类型就是什么类型,不会做类型转换

在这里插入图片描述
其实接口类型变量分为两部分,上面存类型,下面存值,比如cat要存到a1里,bc里就有两个维度的信息,类型,具体的值
在这里插入图片描述
接口类型存储的分两部分,类型和值,刚才打印的类型,就是上面的这个类型,这样就可以存任何类型,不单是一个类型

在这里插入图片描述

接口可以存任何类型,值,初始的适合都是nil空,

在这里插入图片描述
最开始的动态类型是nil,动态值也是nil,剩下的就是存引用类型

在这里插入图片描述

P66 指针接收者实现接口和值接收者实现接口的区别

在这里插入图片描述
可以用值接收者,也可以用指针接收者

在这里插入图片描述
使用值接收者

在这里插入图片描述
这是使用值接收者实现了接口的所有方法,c2是指针,c1是值
在这里插入图片描述
一个是值,一个是指针

在这里插入图片描述
用指针接收者去实现接口,实现animal接口的是cat的指针类型,值是存不进去的,只能存地址
在这里插入图片描述
使用值接收者实现接口和使用指针接收者实现接口的区别?
使用值接收者,不管保存的是结构体还是结构体的指针都能存进去。
使用指针接收者,就只能传指针。
大部分用的是指针接收者

在这里插入图片描述

P67 实现多个接口和接口嵌套

同一个结构体可以实现多个接口,猫实现了move和eater接口
在这里插入图片描述
接口可以嵌套
在这里插入图片描述

P68 空接口

如果一个变量实现了接口里的所有方法,如果没有方法,任何类型都实现了这个接口
在这里插入图片描述
这就是一个空接口的类型
在这里插入图片描述
空接口没有必要起名字,所有类型都实现了空接口,也就是任意类型的变量都能保存到空接口中。
在这里插入图片描述
当不知道要保存什么类型的时候,可以写一个空接口。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
前面是类型,后面是value
在这里插入图片描述
空接口可以存储任意类型的值,那如何获取存储的数据
在这里插入图片描述
在这里插入图片描述
如何拿到值,就需要类型断言,断言就是猜的意思
在这里插入图片描述
在这里插入图片描述
猜不对还需要继续猜,可以试试switch
在这里插入图片描述

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

在这里插入图片描述
进行判断
在这里插入图片描述
在这里插入图片描述
只有当两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义皆苦。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。
在这里插入图片描述

P69 package相关

go语言包,也是组织go语言的一个单位,比如fmt包,os包,io包

在这里插入图片描述
定义一个包,包了里就提供一个add函数,包里的变量名需要首字母大写,才能被外部引用
在这里插入图片描述

要导入这个包,需要指定路径,只有main包才能编译成一个可执行文件,默认目录名当作一个包名
在这里插入图片描述
如果文件夹名和包名不一样,可以起一个别名,后面是路径名
在这里插入图片描述
一个包假如要引用另一个包里的标识符(如变量,常量,类型,函数等),标识符的首字母必须大写

在这里插入图片描述
包的导入就是import语句,导入的包名要用双引号括一起。
在这里插入图片描述
保存以后会自动帮你空一行,代表上面是标准库,下面是第三方的包
在这里插入图片描述
包名是从$GOPATH/src目录开始算
在这里插入图片描述
从这个路径往后写
在这里插入图片描述
go之前还无法解决引用其他包版本的问题,只能把包的源代码下载到本地运行,后面可以用gomod
在这里插入图片描述
禁止循环导入,a导b,b导c,c导a,go编译的时候,是先从main包找起,然后找到了别人的包,把这里的代码和自己的代码打包成一个整体。
在这里插入图片描述
在这里插入图片描述
比如导入数据库的包,不用它的方法,用它链接数据库的那一段代码,但没有用到包的任何方法
在这里插入图片描述
这样说白了只执行包里的init方法

在这里插入图片描述
go语言导入包的时候,会自动触发init函数的调用。没有参数,没有返回值,不能手动调用,只能自动调用

在这里插入图片描述
在这里插入图片描述
先执行导入包的语句,再执行main的init

在这里插入图片描述
搜索到全局变量的声明后,就会执行init

在这里插入图片描述
这样就代表先全局声明变量,再执行int了

在这里插入图片描述
如果导入多个包,每个包都有init函数,那么这样的执行顺序是什么顺序。
main导入a,a导入b,b导入c,执行的时候需要先执行c的init,然后b的init

在这里插入图片描述
包的路径从GOPATH/src后面的路径开始。
要想被别的包调用标识符必须要首字母大写。
导入包的时候可以指定别名。
导入包的时候不想要使用包内部的标识符,需要使用匿名导入。
每个包导入的时候会自动执行一个名为init()的函数,他没有参数有没有返回值,不能手动调用。
多个包都定义了init(),则他们的执行顺序见下图

在这里插入图片描述

P70 为什么要有日志库作业

在这里插入图片描述

P71 打开文件读内容

os.Open()可以打开一个文件,返回的是一个*File ,file类型的指针和一个错误err,要关闭文件需要用close()方法

在这里插入图片描述
在这里插入图片描述
打开文件其实就是跟操作系统要一个操作接口,需要最后释放,可以使用defer close

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

这是一个Read方法,接收者,参数,return,[]byte其实是一个字节的切片
在这里插入图片描述
可以指定读的长度,下面是简写,数组可以切片,这样代表依次读128个,读到切片里
在这里插入图片描述
如果读128个,那么n就是128,
在这里插入图片描述
读出来的文件
在这里插入图片描述
写个for循环,如果要读128个字节,已经到末尾了,n就是0,就需要退出,如果有129个字节,一词读128个,剩下1个,那么n就不等于0,下次再读就读不到了
在这里插入图片描述

在这里插入图片描述
只有129个字节,第一次读了128,下次再读,只有一个就不满足条件 ,就不会去读
在这里插入图片描述
这样就会去读,小于128说明,没读满,说明读完了

在这里插入图片描述
最后一次读的肯定没有128

在这里插入图片描述
读的时候,也可能有各种错,比如中间文件被移走了
在这里插入图片描述
固定字节读循环是比较low的,还有一种优雅的方式是用bufio,相当于你从磁盘读文件,先放到缓冲区里,再读到程序里。

在这里插入图片描述
在这里插入图片描述
NewReade表示新的读的动作的执行者

在这里插入图片描述
在这里插入图片描述
下面是利用bufio
在这里插入图片描述
创建一个read读对象,然后for循环即可
在这里插入图片描述
只读了一行,因为没有循环读
在这里插入图片描述
写一个for循环,两种情况退出,读完了退出,报错了退出
在这里插入图片描述
现在每一行会多一个空格,println会自带一个空格
在这里插入图片描述
换成print
在这里插入图片描述
在这里插入图片描述
可以使用ioutil这个包,之前把整个文件读出来
在这里插入图片描述
在这里插入图片描述
也是打开文件,close,新建int64变量,n的大小就是读的文件的大小

在这里插入图片描述
肯定也是一个for循环
在这里插入图片描述

P72 文件写入

在这里插入图片描述
打开的模式有几种,wronly只写,create创建文件,rdonly只读,trunc清空,windows的perm是没有用的,linux才有用,0777这样

在这里插入图片描述
没有文件就会报错
在这里插入图片描述
这些是int类型
在这里插入图片描述
其实是16进制数,这些数都是从上到下往左移动,就可以用位
在这里插入图片描述
16进制数1表示1,2表示2
在这里插入图片描述
40转二进制就是这样的
在这里插入图片描述
只读和只写,要么是0 ,要么是1,不能同时出现,位数相或的时候最外位数只能有一个,只要有一个为1就是去
在这里插入图片描述
有些肯定是冲突的,
在这里插入图片描述
只能传一个int,因为可以每个二进制位代表不同的操作
在这里插入图片描述
所以可以把好多的参数进行位于,写到一个参数里
|位于操作

在这里插入图片描述

在这里插入图片描述
位与判断在干嘛

在这里插入图片描述
在这里插入图片描述
只读,没有就创建,有的话就追加
在这里插入图片描述
write写的是字节,writestring写的是字符串
在这里插入图片描述
最后一定要关闭文件,没有就会创建文件
在这里插入图片描述
写入里面的内容
在这里插入图片描述
试试清空
在这里插入图片描述
每次都会清空了写内容

在这里插入图片描述
bufio新建一个写对象
在这里插入图片描述
记得flush,因为之前是写在缓存里的
在这里插入图片描述
在这里插入图片描述
iouitil.WriteFile,往文件写东西

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实现一个copy命令,读文件写到另一个文件里
在这里插入图片描述

P73 使用bufio获取用户输入

在这里插入图片描述
这个scanln相当于读到空白字符,空格或者回车

在这里插入图片描述
新建一个函数,Readerstring 可以一直读到换行符
在这里插入图片描述
现在就可以读取到空格以后的
在这里插入图片描述
这两个都相当于传了文件,不管是os.stdin,还是filedb,都能告诉函数里面有什么东西,所以这两个都需要去实现一个读东西的方法。
在这里插入图片描述
所以newReader()参数就是一个接口类型
在这里插入图片描述
在这里插入图片描述
io.reader就是一个接口类型,不管是标准输入,网络还是文件,都可以读,只要实现reader方法即可。

在这里插入图片描述

P74日志库作业需求

需要分级别,还要写入文件句柄
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值