golang--day5结构体+结构体排序+错误处理+结构体和接口实现面向对象的例子
2023-02-19 10:46 dribs 阅读(25) 评论(0) 编辑 收藏 举报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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | package main import ( "fmt" ) //初始化 type User struct { id int name, addr string float32 //匿名成员变量 必须类型不一样才能区分 } type Point struct { x, y int } //成员方法 //u 称为receiver //等价于func (User)string func (u User) getName() string { return u.name } func (p *Point) setY(v int) { fmt.Printf( "p9set:%+v,%p\n" , p, p) p.y = v } func (p Point) getY() int { return p.y } //构造函数 go本身没有为结构体提供构造器 //但是有时候可以通过一个函数为结构体初始化提供属性值 //从而方便得到一个结构体实例,习惯以Newxxx的形式命名 type Animal struct { name string age int } func NewAnimal(name string, age int) *Animal { //a := Animal{name, age} //fmt.Printf("%+v,%p\n", a, &a) //return &a return &Animal{name, age} //习惯上返回值采用指针类型避免实例的拷贝 } func main() { //1 var声明 非常常用 var u1 User //这种方式声明结构体变量很方便,所有字段都是零值 fmt.Println(u1) fmt.Printf( "%+v\n" , u1) //加上字段打印 fmt.Printf( "%#v\n" , u1) //打印更多信息 //2 字面初始化 推荐 u2 := User{} //字段为零值 fmt.Printf( "u2:%#v\n" , u2) //3 字面量初始化 field:value 为字段赋值 u3 := User{id: 100} fmt.Printf( "u3:%+v\n" , u3) //访问 fmt.Println(u3.id) //修改 u3.id = 200 u3.name = "Tom" fmt.Println(u3) //通过成员方法访问 fmt.Println(u3.getName()) //指针 var p1 = Point{10, 20} //实例 fmt.Printf( "p1:%T,%[1]v\n" , p1) var p2 = &Point{5, 6} //指针 fmt.Printf( "p2:%T,%[1]v\n" , p2) var p3 = new(Point) //new实例化一个结构体并返回 fmt.Printf( "p3:%T,%[1]v\n" , p3) //通过实例修改属性 p1.x = 100 fmt.Printf( "%T,%[1]v\n" , p1) p4 := p1 //多了一个副本,内存地址不一样 fmt.Printf( "p1:%+v %p\n" , p1, &p1) fmt.Printf( "p4:%+v %p\n" , p4, &p4) p5 := &p1 //p5 就是p1的引用了 传递的是一个地址 fmt.Printf( "p5:%+v %p\n" , p5, p5) var p6 = func (p Point) Point { fmt.Printf( "p6inner:%+v,%p\n" , p, &p) return p }(p1) fmt.Printf( "p6outer:%+v,%p\n" , p6, &p6) //可以看出 结构体是非引用类型 使用的是值拷贝,传参活返回值如果使用结构体实例,将产生很多副本 //如何避免多副本,保证函数内外是同一个结构体实例,使用指针 var p7 = func (p *Point) *Point { p.x += 200 fmt.Printf( "p7inner:%+v,%p\n" , p, p) return p }(p5) p7.x += 1 fmt.Printf( "p1:%+v %p\n" , p1, &p1) fmt.Printf( "p7outer: %+v,%p\n" , p7, &p7) p8 := p5 p8.y = 400 //会发生什么?? fmt.Printf( "p1:%+v %p\n" , p1, &p1) fmt.Printf( "p8: %+v,%p\n" , p8, p8) //匿名结构体,标识符直接使用struct部分结构体本身作为类型,而不是使用type定义的有名字的结构体的标识符 //可以使用 var const := 来定义匿名结构体,结构体可以反复定义其实例,但匿名的是一次性的 var point struct { x, y int } fmt.Printf( "匿名结构体:%v\n" , point) //得到的是一个结构体的实例,默认是零值 var message = struct { id int data string }{1, "abc" } //不用零值初始化 注意有个= fmt.Printf( "%v\n" , message) //匿名成员 var u4 = User{id: 10, name: "Bob" , float32: 1.111} //使用类型名float最为字段名 fmt.Println(u4, u4.float32) //构造函数 a := NewAnimal( "Tom" , 18) fmt.Printf( "构造函数:%+v,%p\n" , a, a) //返回的指针和构造函数里一样 //指针类型recevier p9 := Point{66, 88} fmt.Printf( "p9:%+v,%p\n" , p9, &p9) p9.setY(201) //看似是Point{66, 88}实例调用,因为func (p *Point) setY 所以实际是指针,操作同一处地址 fmt.Println(p9.getY()) } |
对切片排序和利用结构体对map排序
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | package main import ( "fmt" "sort" ) type Student struct { Name string Age int } //用于对map的value排序使用,map的格式很像struct格式 type Entry struct { key int value string } type StudentSlice []Student func (x StudentSlice) Len() int { return len(x) } func (x StudentSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x StudentSlice) Less(i, j int) bool { return x[i].Age > x[j].Age } func main() { students := make([]Student, 0, 3) students = append(students, Student{ "Tom" , 19}) students = append(students, Student{ "Jack" , 18}) students = append(students, Student{ "Rose" , 20}) fmt.Println(students) sort.Sort(StudentSlice(students)) fmt.Println(students) //简化版13-23行的代码可以去掉,直接匿名函数实现Less sort.Slice(students, func (i, j int) bool { return students[i].Age < students[i].Age }) fmt.Println(students) //对map排序之对map的key排序,先取出key,放到int[]切片里,然后对int[]切片排序,在根据排序好的切片 获取map对应的value m := make( map [int]string) m[1] = "b" m[2] = "c" m[0] = "a" var keys []int for k := range m { keys = append(keys, k) } sort.Ints(keys) for _, v := range keys { fmt.Println(v, m[v]) } //对map排序之对map的value排序 //创建一个Entry类型的切片,存放字典里的k,v p := make([]Entry, len(m)) i := 0 // for k, v := range m { p[i] = Entry{k, v} i++ } fmt.Println(p) sort.Slice(p, func (i, j int) bool { return p[i].value > p[j].value }) fmt.Println(p) } |
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 | package main import ( "errors" "fmt" "io/fs" "os" ) //panic执行: //逆序执行当前已经注册过的goroutine的defer链(recover从这里介入) //打印错误信息和调用堆栈 //调用exit(2)结束整个进程 //recover 类似python的 try catch 捕获异常 var ErrdivisionByZero = errors.New( "division by zero" ) //构造一个错误实例 func div(a, b int) int { defer func () { err := recover() //一旦recover了,就相当处理过了错误 println(1, err, "====" ) }() defer fmt.Println( "start" ) defer fmt.Println(a, b) defer func () { println( "错误捕获" ) err := recover() switch err.( type ) { //类型断言 case *fs.PathError: println( "文件不存在" , err) case []int: println( "切片" , err) } println( "离开" ) }() if f, err := os.Open( "o:/tttt.txt" ); err != nil { panic(err) } else { println(f) } r := a / b println( "end" ) return r } func main() { println(div(5, 0)) } |
1.计算三角形长方形圆形的面积
2.计算完的面积排序处理
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | package main import ( "fmt" "sort" ) //定义Area接口 用于多态实现 type Areaer interface { area() int } //圆形 type Yuan struct { pi float32 r int } //长方形 type Chang struct { w, l int } //三角形 type San struct { Chang //匿名嵌套长方形,实现继承的效果 } //第二题构建三个以上图形排序的结构体 type AllGraph struct { name string area int } //第二题使用,构造函数 func NewAllGraph(name string, area int) *AllGraph { return &AllGraph{name, area} } //第二题使用排序 type AllgraphSlice []AllGraph func (x AllgraphSlice) Len() int { return len(x) } func (x AllgraphSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] } func (x AllgraphSlice) Less(i, j int) bool { //降序排序 return x[i].area > x[j].area } //实现多态 func foo(a Areaer) int { //a.area() return a.area() } //求三种类型的面积*(圆 长方形 三角形) func (y *Yuan) area() int { area := y.pi * float32(y.r*y.r) //fmt.Printf("圆形面积是:%.f\n", area) return int(area) } func (c *Chang) area() int { area := c.w * c.l //fmt.Printf("长方形面积是:%d\n", area) return area } func (s *San) area() int { area := s.w * s.l / 2 //fmt.Printf("三角形面积是:%d\n", area) return area } func main() { //第一题求面积 //圆形面积 pi*r^2 y1 := &Yuan{3.14, 3} //y1.area() fmt.Printf( "圆形面积是:%d\n" , y1.area()) //长方形面积 长*宽 c1 := new(Chang) c1.w = 3 c1.l = 4 //c1.area() fmt.Printf( "长方形面积是:%d\n" , c1.area()) //三角形面积 底*高/2 ,三角形继承长方形,多态实现求面积 s1 := &San{} s1.w = 10 s1.Chang.l = 4 //foo(s1) fmt.Printf( "三角形面积是:%d\n" , foo(s1)) //+++++++++++++++++++++++++++++++++++++++++++++++++ //第二题对面积排序 使用切片方式排序 //构建三个实例,构建成map也适用 n1 := NewAllGraph( "Yuan" , foo(y1)) n2 := NewAllGraph( "Chang" , foo(c1)) n3 := NewAllGraph( "San" , foo(s1)) alls := []AllGraph{*n1, *n2, *n3} fmt.Println( "排序前:" , alls) //对结构体 降序排序 sort.Sort(AllgraphSlice(alls)) fmt.Println( "排序后:" , alls) //切片排序第二种方法 简易版 sort.Slice(alls, func (i, j int) bool { //升序 return alls[i].area < alls[j].area }) fmt.Println( "升排序:" , alls) //对key string类型排序 var keys []string for i := 0; i < len(alls); i++ { keys = append(keys, alls[i].name) } //区分验证上面的排序准确性 在单独append追加一个string,没写完还要一个map 不想写了 keys = append(keys, "AAA" ) sort.Strings(keys) fmt.Println(keys) } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具