1 接口基础
package main
import "fmt"
type Animal interface {
eat()
sleep()
}
type Dog struct {
name string
age int
}
func (dog Dog) WatchHouse() { fmt.Println("狗看家功能") }
func (dog Dog) eat() { fmt.Println("狗吃东西") }
func (dog Dog) sleep() { fmt.Println("狗睡觉") }
type Cat struct {
name string
age int
}
func (cat Cat) CatchMouse() { fmt.Println("猫抓老鼠") }
func (cat Cat) eat() { fmt.Println("猫吃东西") }
func (cat Cat) sleep() { fmt.Println("猫睡觉") }
func goToSleep(a Animal) {
a.sleep()
}
func main() {
var cat1 = Cat{"cat1", 1}
var dog1 = Dog{"dog1", 1}
var animal1 Animal
animal1 = cat1
fmt.Println(animal1)
animal1 = dog1
fmt.Println(animal1)
goToSleep(cat1)
goToSleep(dog1)
goToSleep(animal1)
}
package main
import "fmt"
type Animal interface {
eat()
sleep()
}
type Dog struct {
name string
age int
}
func (dog Dog) WatchHouse() { fmt.Println("狗看家功能") }
func (dog Dog) eat() { fmt.Println("狗吃东西") }
func (dog Dog) sleep() { fmt.Println("狗睡觉") }
type Cat struct {
name string
age int
}
func (cat Cat) CatchMouse() { fmt.Println("猫抓老鼠") }
func (cat Cat) eat() { fmt.Println("猫吃东西") }
func (cat Cat) sleep() { fmt.Println("猫睡觉") }
func goToSleep(a Animal) {
a.sleep()
}
type Empty interface{}
func myPrint(a Empty) {fmt.Println(a)}
func myPrint2(a interface{}) {fmt.Println(a)}
func testDog (a Animal) {
dog := a.(Dog)
fmt.Println(dog)
}
func testDog2 (a Animal) {
dog,ok := a.(Dog)
fmt.Println(dog,ok)
}
func testDog3(a Animal) {
dog,ok := a.(Dog)
if ok{
dog.WatchHouse()
}
}
func testDog4(a Animal) {
if dog,ok:=a.(Dog);ok{
dog.WatchHouse()
}
}
func testDog5(i interface{}) {
switch obj:=i.(type) {
case Dog:
obj.WatchHouse()
case Cat:
obj.CatchMouse()
case int:
fmt.Println("这是int类型")
case string:
fmt.Println("这是string类型")
default:
fmt.Println("其他类型")
}
}
func main() {
var cat1 = Cat{"cat1", 1}
var dog1 = Dog{"dog1", 1}
var animal1 Animal
animal1 = cat1
fmt.Println(animal1)
animal1 = dog1
fmt.Println(animal1)
goToSleep(cat1)
goToSleep(dog1)
goToSleep(animal1)
myPrint(10)
myPrint("cx")
var a2 [3]int
myPrint(a2)
var i2 interface{}
i2 = 0
fmt.Println(i2)
i2 = "cx"
fmt.Println(i2)
testDog(dog1)
testDog2(dog1)
testDog2(cat1)
testDog3(dog1)
testDog3(cat1)
testDog5(cat1)
testDog5(dog1)
testDog5(100)
testDog5("cx")
testDog5([3]int{1,2,3})
var animal2 Animal1
fmt.Println(animal2)
}
2 接口高级
package main
import "fmt"
type Animal1 interface {
eat()
}
type Duck struct {
name string
}
func (duck Duck) eat() {
fmt.Println("鸭子吃", duck)
}
type Chicken struct {
name string
}
func (chicken *Chicken) eat() {
fmt.Println("鸡吃", chicken)
}
type Animal2 interface {
eat()
}
type Duck2 interface {
run()
speak()
Animal2
}
type Animal3 interface {
eat()
}
type Duck3 interface {
run()
speak()
Animal3
}
type tDuck struct {
name string
age int
}
func (duck tDuck) eat() {fmt.Println("duck eat")}
func (duck tDuck) speak() {fmt.Println("duck speak")}
func (duck tDuck) run() {fmt.Println("duck run")}
func main() {
duck := Duck{"鸭子"}
chicken := Chicken{"鸡"}
duck.eat()
chicken.eat()
duck1 := &Duck{"鸭子"}
chicken1 := &Chicken{"鸡"}
duck1.eat()
chicken1.eat()
var animal1 Animal1 = duck
animal1.eat()
var animal11 Animal1 = &duck
animal11.eat()
var animal2 Animal1 = &chicken
animal2.eat()
var duck3 = tDuck{"t_duck",1}
var animal3 Animal3 = duck3
var duckInt Duck3 = duck3
fmt.Println(animal3, duckInt)
}
3 并发和并行
4 go协程
package main
import (
"fmt"
"time"
)
// Go协程(线程池+协程) goroutine
func printHello() {
fmt.Println("hello")
}
------------------------------------------
func main() {
fmt.Println("程序开始了")
printHello()
fmt.Println("程序结束了")
// 1 开启goroutine
fmt.Println("程序开始了")
go printHello() // 开启协程
go printHello() // 开启协程
time.Sleep(1*time.Second) // 只传1是1纳秒,等一秒是为了让协程执行打印hello完毕,否则执行主程序完毕后可能协程还没有执行完毕。此时开启的协程将会被关闭
fmt.Println("程序结束了")
}
------------------------------------------
// 2 同时开启多个goroutine,尽管用,开上万个都没问题
func main() {
fmt.Println("程序开始了")
go printHello()
go printHello()
go printHello()
...
...
time.Sleep(1*time.Second)
fmt.Println("程序结束了")
}
------------------------------------------
// 开启多个goroutine,可以利用多核优势
func loop_dead(name string) { // 死循环函数
for {
fmt.Println(name)
}
}
func main() {
// goroutine 能够利用多核优势
// python 如果想利用多核优势,必须开多进程
// 8核cpu,开一个死循环,只能占住1核,cpu的使用率,只占八分之一
// 如果使用python 开启多个线程,无论开多少个,如果是8核cpu,都只占八分之一
go loop_dead("cx1")
go loop_dead("cx2")
go loop_dead("cx3")
go loop_dead("cx4")
go loop_dead("cx5")
go loop_dead("cx6")
}
----------------------------------------
/*
补充:
在main或其他函数中开协程,主程序结束了,协程还继续执行吗?
结论:main函数中的协程,如果main结束了,协程也会结束
其他函数里的协程,函数结束了,只要main没结束,协程就会执行。
*/
5 信道
package main
import (
"fmt"
"time"
)
func go1(a chan bool) {
fmt.Println("其他goroutine开始")
time.Sleep(time.Second * 2)
a <- true
fmt.Println("其他goroutine结束")
}
func main() {
var c chan bool = make(chan bool)
fmt.Println("主的goroutine开始")
go go1(c)
b := <-c
fmt.Println("主的goroutine结束,接收了b为:", b)
var c2 chan interface{}
fmt.Println(c2)
var c21 = make(chan interface{})
fmt.Println(c21)
}
package main
import "fmt"
func calcSquares(number int,a chan int) {
total:=0
for number!=0{
digit := number % 10
total+=digit*digit
number=number/10
}
a<-total
}
func calcCubes(number int,b chan int) {
total:=0
for number!=0{
digit := number % 10
total+=digit*digit*digit
number=number/10
}
b<-total
}
func main() {
number:=889
var a =make(chan int)
var b =make(chan int)
go calcSquares(number,a)
go calcCubes(number,b)
res1, res2 := <-a, <-b
fmt.Println(res1+res2)
}
package main
import "fmt"
func task1(c chan<- int) {
c <- 9
}
func main() {
c := make(chan int)
go task1(c)
<-c
}
package main
import "fmt"
func producer(chnl chan int) {
for i := 0; i < 10; i++ {
chnl <- i
fmt.Println("放入", i)
}
close(chnl)
}
func main() {
ch := make(chan int)
go producer(ch)
for {
v, ok := <-ch
if ok == false {
break
}
fmt.Println("Received ", v, ok)
}
go producer(ch)
for v := range ch {
fmt.Println("取出: ", v)
}
}
4 缓冲信道
package main
import "fmt"
func main() {
var a1 =make(chan int,3)
a1<-999
a1<-888
a1<-777
fmt.Println(a1)
<-a1
<-a1
fmt.Println(<-a1)
var c =make(chan int)
fmt.Println(len(c))
fmt.Println(cap(c))
var c2 =make(chan int,3)
fmt.Println(len(c2))
fmt.Println(cap(c2))
c2<-999
c2<-888
fmt.Println(len(c2))
fmt.Println(cap(c2))
c2<-888
var c3 =make(chan entity.Person,3)
c3<-entity.NewPerson("lqz",19,"lyf")
var p entity.Person=<-c3
fmt.Println(p)
}
5 WaitGroup
package main
import (
"fmt"
"sync"
)
func task3(s string,c chan int) {
fmt.Println("打印",s)
c<-999
}
func main() {
fmt.Println("主开始了")
var c =make(chan int,3)
go task3("lqz",c)
go task3("111",c)
go task3("222",c)
for i:=0;i<cap(c);i++{
<-c
}
fmt.Println("主结束了")
}
func task3(s string, wg *sync.WaitGroup) {
fmt.Println(s)
wg.Done()
}
func main() {
fmt.Println("主开始了")
var wg sync.WaitGroup
fmt.Println(wg)
go task3("lqz", &wg)
go task3("111", &wg)
go task3("222", &wg)
wg.Add(3)
wg.Wait()
fmt.Println("主结束了")
fmt.Println("主开始了")
var wg2 sync.WaitGroup
for i := 0; i < 5; i++ {
go task3("ssss", &wg2)
wg2.Add(1)
}
wg2.Wait()
fmt.Println("主结束了")
}
7 defer的使用
package main
import "fmt"
// defer的使用---》注册代码,延迟调用,等函数执行完后,按注册顺序倒序执行defer,先注册的,最后执行
// 如果打开一个文件,最后要关闭,一打开文件,立马用defer注册关闭
--------------------------------------------
func main() { // 顺序:开始 结束 3 2 1
fmt.Println("我开始执行了")
defer fmt.Println("我是defer注册的代码1")
defer fmt.Println("我是defer注册的代码2")
defer fmt.Println("我是defer注册的代码3")
fmt.Println("我执行结束了")
}
--------------------------------------------
func main() { // 顺序:开始 结束 10
fmt.Println("我开始执行了")
var a int=10
defer func(i int) {
fmt.Println("我是匿名函数的执行")
fmt.Println(i)
}(a) // 已经传入,但是没执行,copy传递,复制了一份a=10传入了
a++ // a 自增1
fmt.Println("我执行结束了")
}
--------------------------------------------
func main() { // 顺序:开始 结束 11
fmt.Println("我开始执行了")
var a int=10
defer func() {
fmt.Println("我是匿名函数的执行")
fmt.Println(a) // 对外部的引用 , 打印出11
}()
a++ // a 自增1
fmt.Println("我执行结束了")
}
--------------------------------------------
func main() { // 顺序:开始 结束 [999,7,8]
fmt.Println("我开始执行了")
var a =[]int{6,7,8}
defer func() {
fmt.Println("我是匿名函数的执行")
fmt.Println(a) // 对外部的引用 , [999,7,8]
}()
a[0]=999
fmt.Println("我执行结束了")
}
--------------------------------------------
func main() { 顺序:开始 结束 [999,7,8]
fmt.Println("我开始执行了")
var a =[]int{6,7,8}
defer func(s []int) {
fmt.Println("我是匿名函数的执行")
fmt.Println(s) // 虽然是copy传递,但是s是引用,改了会影响原来的[999,7,8]
}(a)
a[0]=999
fmt.Println("我执行结束了")
}
--------------------------------------------
func main() { // 顺序:开始 结束 循环第0123456789 10 0
fmt.Println("我开始执行了")
i:=0
defer fmt.Println("普通目前i的值是:",i) // 0
defer func() { // 对外部的引用
fmt.Println("函数内目前i的值是:",i) //10
}()
defer func() { // 对外部的引用
for ;i<10;i++{
fmt.Println("循环第:",i)
}
}()
fmt.Println("我执行结束了")
}
8 panic和recover
package main
import "fmt"
// defer : 先注册,后执行,即便程序报了panic的错误,也会执行
// panic : 跟python中raise,java中throw是一样的,主动抛出异常
// recover: 恢复程序,继续执行
func main() {
fmt.Println("主开始了")
panic("我出错了")
fmt.Println("主结束了") // 永远不会被执行到
}
----------------------------------
// panic 主动抛出异常
func test8() {
fmt.Println("我是test8")
panic("我出错了")
fmt.Println("我是test8,我执行完了")
}
func main() {
fmt.Println("主开始了")
test8()
fmt.Println("主结束了") // 永远不会被执行到
}
----------------------------------
func test8(s []int) {
fmt.Println(s)
fmt.Println(s[9]) // 越界,报错,抛异常,程序抛出的
}
func main() {
var s=[]int{7,8,9}
test8(s)
fmt.Println("我结束了") // 不会被执行
}
----------------------------------
// 程序出异常,捕获异常,处理异常,程序继续执行
func test8(s []int) {
defer func() { // 即使报错后也会执行,所以报错后可以恢复、但报错后代码不会运行
recover()
}()
fmt.Println(s)
fmt.Println(s[9]) // 越界,报错,抛异常,程序抛出的
}
func main() {
var s=[]int{7,8,9}
test8(s)
fmt.Println("我结束了") // 会运行
}
----------------------------------
/*
Python异常处理:
try:
f2()
except Exception as e:
print(e)
finally:
print(无论是否出错,都会执行)
*/
// go 语言中异常处理
func main() {
fmt.Println("我开始了")
f1()
f2() // 知道f2会异常,我想后面的继续执行
f3()
fmt.Println("我结束了")
}
func f1() {
fmt.Println("我是f1")
}
func f2() {
defer func() {
//recover() // 恢复程序,如果有错误,会返回错误对象,如果没有错误,会返回nil
if err:=recover();err!=nil{ // 说明出错了
fmt.Println(err) // 打印错误
}
fmt.Println("这是其他语言finally的代码")
}()
//panic("我主动抛出")
//var a =[]int{9,8,7}
//fmt.Println(a[9])
fmt.Println("我是f2")
}
func f3() {
fmt.Println("我是f3")
}
----------------------------------
// 总结:go 中异常捕获:把这段代码,放到可能会出错代码的上方
defer func() {
if err:=recover();err!=nil{
// except的代码
}
//finally的代码
}()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?