1 接口
package main
import (
"fmt"
)
//接口:一系列方法的集合,规范的对象的行为
//
//匿名空接口
//类型断言
//类型选择
//实现多个接口
//接口嵌套
// 接口零值
//1 定义一个鸭子接口(run方法 speak方法)
type DuckInterface interface {
run()
speak()
}
//写一个唐老鸭结构体,实现该接口
type TDuck struct {
name string
age int
wife string
}
//实现接口(只要结构体绑定了接口中的所有方法,就叫做:结构体实现了该接口)
// 同一类事物的多种形态
func (t TDuck) run() {
fmt.Println("我是唐老鸭,我的名字叫", t.name, "我会人走路")
}
func (t TDuck) speak() {
fmt.Println("我是唐老鸭,我的名字叫", t.name, "我说人话")
}
//写一个肉鸭结构体,实现该接口
type RDuck struct {
name string
age int
}
//实现接口(只要结构体绑定了接口中的所有方法,就叫做:结构体实现了该接口)
func (t RDuck) run() {
fmt.Println("我是肉鸭,我的名字叫", t.name, "我会人走路")
}
func (t RDuck) speak() {
fmt.Println("我是肉鸭,我的名字叫", t.name, "我说人话")
}
// 1 空接口(所有类型都实现了空接口)
//type Empty interface {
//}
// 2 匿名空接口
func main() {
//var a Empty =[3]int{1,2,3}
//fmt.Println(a)
//匿名空接口
//var a interface{}="xxx"
//fmt.Println(a)
//3 类型断言
//i1 := TDuck{"嘤嘤怪", 18, "刘亦菲"}
//i2 := RDuck{"建哥", 18}
////这两个类型都实现了DuckInterface接口,可以当做DuckInterface的类型
////test(i1)
//test(i2)
//4 类型选择
//i1 := TDuck{"嘤嘤怪", 18, "刘亦菲"}
//i2 := RDuck{"建哥", 18}
//i3:=1
//i4:="xx"
//test(i1)
//test(i2)
//test(i3)
//test(i4)
//test(4.5)
}
//3 类型断言
//func test(i DuckInterface) {
// //接口类型没有属性,取不到鸭子的name
// //我断定你是TDuck类型
// var t TDuck=i.(TDuck) //如果断言失败,就报错
// fmt.Println(t.wife)
//}
//4 类型选择
//func test(i interface{}) { //可以接收任意类型的参数
// switch a:=i.(type) {
// case int:
// fmt.Println("我是int")
// case string:
// fmt.Println("我是字符串")
// case TDuck:
// fmt.Println("我是TDuck类型")
// //打印出wife
// fmt.Println(a.wife)
// case RDuck:
// fmt.Println("我是RDuck类型")
// fmt.Println(a.name)
// default:
// fmt.Println("未知类型")
// }
//}
package main
//接口
//4 实现多个接口
//type SalaryCalculator interface {
// DisplaySalary()
//}
//
//type LeaveCalculator interface {
// CalculateLeavesLeft() int
//}
//
//type Employee struct {
// firstName string
// lastName string
//}
//
//func (e Employee)DisplaySalary() {
// fmt.Println("xxxxx")
//}
//
//func (e Employee)CalculateLeavesLeft() int {
// return 1
//}
// 5 接口嵌套
type SalaryCalculator interface {
DisplaySalary()
run()
}
//type LeaveCalculator interface {
// SalaryCalculator
// //DisplaySalary()
// //run()
// CalculateLeavesLeft()
//}
type Employee struct {
firstName string
lastName string
}
func (e Employee)DisplaySalary() {
}
func (e Employee)run() {
}
func (e Employee)CalculateLeavesLeft() {
}
func main() {
//4 实现多个接口,就可以赋值给不通的接口类型
//var a SalaryCalculator
//var b LeaveCalculator
//var c Employee=Employee{}
//a=c
//b=c
//4 接口嵌套
//var c Employee=Employee{}
//var b LeaveCalculator
//b=c
//5 接口零值:是nil类型,接口类型是引用类型
//var a LeaveCalculator
//fmt.Println(a)
//侵入式接口和非侵入式接口
//java:侵入式接口,修改,删除:对子类有影响
//go,Python:非侵入式接口 修改,删除:对子类有没有影响
}
2 go协程
package main
import (
"fmt"
"time"
)
//并发和并行
// 并发:假如在他晨跑时,鞋带突然松了。于是他停下来,系一下鞋带,接下来继续跑
// 并行: 假如这个人在慢跑时,还在用他的 iPod 听着音乐(必须多核cpu)
// goroutine:go的协程(并不是真的协程:统称,有线程也有协程)线程池 go 任务丢到线程池中
//(进程 线程:是cpu调度的最小单位 协程:单线程下实现并发,微线程,用户自己控制的线程)
// go 协程
func test1() {
fmt.Println("go go go")
}
func main() {
// go 关键字,就并发起来了
fmt.Println("我是mian")
//go test1()
//go test1()
//go test1()
//go test1()
//go test1()
for i:=0;i<10000000;i++{
go test1()
}
time.Sleep(1*time.Second)
}
// 输入一个数字 345
//计算 3的平方+4的平方+5的平方 函数 5s 5s
//计算 3的立方+4的立方+5的立方 函数 10s 10s
//上面两个结果加起来 1s 16s 1s 11s
3 信道
package main
import (
"fmt"
"time"
)
//信道:信道可以想像成 Go 协程之间通信的管道。如同管道中的水会从一端流到另一端,通过使用信道,数据也可以从一端发送,在另一端接收。
//信道就是一个变量
//channle:通道/信道
func test2(a chan int) {
fmt.Println("go go go")
time.Sleep(time.Second*2)
//执行完成,往信道放一个数字1
a<-1
fmt.Println("xxxx")
}
func main() {
//1 定义一个信道(运输信息的类型是固定的)
//var a chan int
//2 零值(nil:引用类型)
//fmt.Println(a)
//3 通过信道进行发送和接收
//定义并初始化一个int类型信道(make 来初始引用类型)
//var a chan int=make(chan int)
////引用类型,不需要取地址
//go test2(a)
////c:=<-a
//<-a
////fmt.Println(c)
//time.Sleep(time.Second*1)
//3.1 信道往里放值和往外取值
//var b chan int=make(chan int)
//b<-1 //往管道中放一个1
//<-b //从管道中取出一个值
//var c int =<-b //从管道中取出一个值
//4 发送和接收,默认都是阻塞的
var b chan int=make(chan int)
b<-1 // deadlock
//5 案例s101.go
//6 单向信道,只写或者只读 (双向信道:可以写,可以读) s102.go
//7 关闭信道 close s103.go
}
4 缓冲信道
package main
import "fmt"
// 有缓冲信道:管子可以放多个值
func main() {
//1 定义
//var a chan int =make(chan int,0) //无缓冲信道
//var a chan int =make(chan int,5) //定义一个长度为5的有缓冲信道
////可以塞5个 int,在塞满之前,是不阻塞的
//a<-1
//a<-2
//a<-3
//a<-4
//a<-5
//a<-6 //超了5个,会出现死锁
//fmt.Println(<-a)
//fmt.Println(<-a)
//fmt.Println(<-a)
//fmt.Println(<-a)
//fmt.Println(<-a)
//
//fmt.Println(<-a)// 取第6个,死锁
//2 长度和容量
//len cap
var a chan int =make(chan int,5)
a<-2
a<-3
fmt.Println(len(a)) //2
fmt.Println(cap(a)) //5
}
5 defer panic 和recover
package main
import "fmt"
//异常处理 try 没有这个关键字
//defer :延迟执行
//panic :主动抛出异常 python中raise
//recover:恢复程序,继续执行
// 捕获异常并且让程序继续执行
//func f1() {
// fmt.Println("f1")
//}
//func f2() {
// fmt.Println("f2")
// //var a []int=[]int{1,2}
// //fmt.Println(a[10])
// panic("我出异常了")
//}
//func f3() {
// fmt.Println("f3")
//}
//
//func main() {
// f1()
// f2()
// f3()
//}
// defer:延迟执行,即便程序出现严重错误
//func main() {
// defer fmt.Println("我最后执行") //先注册,等函数执行完成,再倒着执行defer的内容
// defer fmt.Println("888888")
// fmt.Println("xxx")
// panic("严重出错了")
// fmt.Println("yyyy")
//}
//异常处理
//func f1() {
// fmt.Println("f1")
//}
//func f2() {
// //defer fmt.Println("我会执行")
// //在这捕获异常,把异常解决掉
//
// defer func() {
// if err := recover(); err != nil { //recover执行,如果等于nil 表示没有异常,如果有值,表示出错,err就是错误信息
// fmt.Println(err)
// }
// fmt.Println("我是finally的东西")
// }()
//
// fmt.Println("f2")
// //panic("我出异常了")
//
// //fmt.Println("我不会执行")
// //defer fmt.Println("xxx") //如果没有注册,肯定不会执行
//}
//func f3() {
// fmt.Println("f3")
//}
//
//func main() {
// f1()
// f2()
// f3()
//}
//终极总结异常处理,以后要捕获哪的异常,就在哪写
//defer func() {
// if err := recover(); err != nil { //recover执行,如果等于nil 表示没有异常,如果有值,表示出错,err就是错误信息
// fmt.Println(err)
// }
// fmt.Println("我是finally的东西")
//}()
//func main() {
//
// fmt.Println("xxx")
// //defer func() {
// // if err := recover(); err != nil { //recover执行,如果等于nil 表示没有异常,如果有值,表示出错,err就是错误信息
// // fmt.Println(err)
// // }
// // fmt.Println("我是finally的东西")
// //}()
// panic("我出异常了")
//}
func main() {
fmt.Println("xxx")
fmt.Println("uyyy")
defer fmt.Println("7777")
fmt.Println("yyyeee")
//打开文件
//立马写一个defer 文件对象.close()
//处理文件
//趴。出异常了,程序崩掉
//从这个位置开始,倒着执行defer
}