Go语言的学习之旅【六】
一、接口
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 | type Car interface { //定义一个Car的接口 what() //定义一个方法 } type Bicycle struct { } type Motor struct { } func (bicycle Bicycle) what() { fmt.Println( "I am Bicycle" ) } func (bicycle Bicycle) speed() { fmt.Println( "I am Bicycle,speed 15km/h" ) } func (motor Motor) what() { fmt.Println( "I am Motor" ) } func main() { var car Car car = new(Bicycle) car.what() car = new(Motor) car.what() var bicycle = new(Bicycle) //这个代表一个指针 bicycle.speed() } |
二、错误异常
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | // 定义一个 DivideError 结构 type DivideError struct { dividee int divider int } // 实现 `error` 接口 func (de *DivideError) Error() string { strFormat := ` Cannot proceed, the divider is zero. dividee: %d divider: 0 ` //fmt.Println("de:",&de) return fmt.Sprintf(strFormat, de.dividee) } // 定义 `int` 类型除法运算的函数 func Divide(varDividee int, varDivider int) (result int, errorMsg string) { if varDivider == 0 { dData := DivideError{ dividee: varDividee, divider: varDivider, } errorMsg = dData.Error() //fmt.Println("dData:",&dData) return } else { return varDividee / varDivider, "" } } func Sqrt(f float64) (float64, error) { if f < 0 { return 0, errors.New( "math: square root of negative number" ) } return math.Sqrt(f), nil } func main() { var a, err = Sqrt(10) if err != nil { fmt.Println(a, err) } // 正常情况 if result, errorMsg := Divide(100, 10); errorMsg == "" { fmt.Println( "100/10 = " , result) } // 当除数为零的时候会返回错误信息 if _, errorMsg := Divide(1000, 0); errorMsg != "" { fmt.Println( "errorMsg is: " , errorMsg) } } |
三、并发
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } } func sum(s []int, c chan int) { sum := 0 for _, v := range s { sum += v } fmt.Println(sum) c <- sum //把sum值发送到通道c } func main() { //go say("world") //开启新的线程 //say("hello") //主线程,运行可以看到world跟hello打印没有顺序,证明两个同时进行 s := []int{7, 2, 8, -9, 4, 0} c := make( chan int) //默认通道,需要一发一收 go sum(s[:len(s)/2], c) //并发计算,里面发送信号到通道c go sum(s[len(s)/2:], c) //并发 x, y := <-c, <-c //这里接收c的通信 fmt.Println(x, y, x+y) //如果构建通道时,给与缓存,可以一次性多发送,再一次性多接收 // 因为 ch 是带缓冲的通道,我们可以同时发送两个数据 // 而不用立刻需要去同步读取数据 ch := make( chan int, 2) ch <- 1 ch <- 2 u, v := <-ch, <-ch fmt.Println(u, v) ch2 := make( chan int, 10) go fibonacci(cap(ch2), ch2) // range 函数遍历每个从通道接收到的数据,因为 c 在发送完 10 个 // 数据之后就关闭了通道,所以这里我们 range 函数在接收到 10 个数据 // 之后就结束了。如果上面的 c 通道不关闭,那么 range 函数就不 // 会结束,从而在接收第 11 个数据的时候就阻塞了。 for i := range ch2 { fmt.Println(i) } } func fibonacci(n int, c chan int) { x, y := 0, 1 for i := 0; i < n; i++ { c <- x x, y = y, x+y } close(c) } |
四、总结
go语言接口方面设计确实很简洁,实现接口里的方法只要对应的结构体实现。错误处理看起来只是简单的方法调用。并发上确实简单,调用时直接加go关键词,就会新开线程同步执行。还有关于通信接收,还只是初步了解,默认情况下通道只有1,接收要同步,一发一收,否则就会阻塞形成死锁。如果给通道设置容量,可以多发多收。接触了go语言,确实在一方面有突出的点。接着会学习goweb的开发!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!