Go语言的学习之旅【五】
一、切片Slice
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 | func main() { fmt.Println( "Hello, World!" ) s := []int{1, 2, 3} //数组 printSlice(s) fmt.Println(s[0:2]) //使用切片方式 fmt.Println(s[:2]) fmt.Println(s[0:]) fmt.Println(s[:]) s2 := make([]int, 3, 5) //通过make([]int, len, cap)来定义切片 printSlice(s2) var s3 []int if s3 == nil { fmt.Println( "s3切片为空" ) } printSlice(s3) var s4 []int s4 = append(s4, 0) //向s4空切片追加数据 printSlice(s4) s4 = append(s4, 1) //向s4追加1个数据 printSlice(s4) s4 = append(s4, 2,3,4) //向s4追加多个数据 printSlice(s4) s5 := make([]int, len(s4), cap(s4) * 2) //创建s5切片,容量是其两倍 printSlice(s5) copy(s5, s4) //将s4的内容拷贝到s5中 printSlice(s5) s5 = append(s5, 6,7,8,9,10,11,12,13) //当添加的数据大于容量,会自动扩容 printSlice(s5) //s5[13] = 14 //使用下标的情况,需要小于长度 s5 = append(s5, 14,15,16,17,18,19,20,21,22,23,24,25) printSlice(s5) //可以看到cap容量扩容都是两倍扩容 } func printSlice(x []int){ //切片不仅能使用len()来进行测量长度,还提供了cap()函数测量容量 fmt.Printf( "len=%d cap=%d slice=%v\n" ,len(x),cap(x),x) } |
二、范围Range
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | func main() { fmt.Println( "Hello, World!" ) arr := []int{1, 2, 3} for num := range arr { //如果定义一个变量来接收,是其下标值 fmt.Println(num) } for i, num := range arr { //i是下标,num是值,可以看出key,value两个返回值 fmt.Println(i, "" , num) } for _, num := range arr { //如果不需要其中的某个返回值,直接用`_`来代替 fmt.Println(num) } m := map [string]string{ "a" : "apple" , "b" : "banana" } for k, v := range m { //循环哈希表 fmt.Println(k,v) } s := "golang" for i,c := range s{ //循环字符串,第一个参数是字符的索引,第二个是字符(Unicode的值)本身。 fmt.Println(i,c) } } |
三、集合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 | var m map [string]string //声明map, map[key类型]value类型 m2 := make( map [string]string) //用make声明map if m == nil { //空map fmt.Println(m) } m2[ "abc" ] = "ABC" //存入值 fmt.Println(m2[ "abc" ]) //取出值 m2[ "啊" ] = "啊啊啊" for k, v := range m2 { //循环取值 fmt.Println(k, v, m2[k]) } val, ok := m2[ "abc" ] //两个返回值,第一个是值,第二个是状态 fmt.Println( "val,ok:" , val, ok) fmt.Println(m2) delete(m2, "abc" ) //删除 key为abc fmt.Println(m2) //链表 type LinkMap struct { key string value string next *LinkMap } alink := LinkMap{ "a" , "A" ,nil} blink := LinkMap{ "b" , "B" ,nil} alink.next = &blink //只能存储其地址 fmt.Println(alink,alink.next) //struct{}无是一个无元素的结构体类型,通常在没有信息存储时使用。优点是大小为0,不需要内存来存储struct {}类型的值。 //struct {} {}是一个复合字面量,它构造了一个struct {}类型的值,该值也是空。 var set map [string] struct {} //这个就形成set,因为struct{}{}是相等的 // Add some values to the set: set[ "red" ] = struct {}{} set[ "blue" ] = struct {}{} // Check if a value is in the map: _, ok := set[ "red" ] fmt.Println( "Is red in the map?" , ok) //结果是存在 _, ok = set[ "green" ] fmt.Println( "Is green in the map?" , ok) //结果不存在 |
四、递归
1 2 3 4 5 6 7 8 9 10 | func Factorial(n uint32) (res uint32) { //来个阶乘n!,递归 if n > 0 { return n * Factorial(n-1) } return 1 } func main() { res := Factorial(10) fmt.Println(res) } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | func Fibonacci(n int) int { //斐波那契数列 if n < 2 { return n } return Fibonacci(n-1) + Fibonacci(n-2) } func main() { var i int for i = 0; i < 10; i++ { res := Fibonacci(i) fmt.Println(res) } } |
五、类型转换
1 2 3 4 5 6 7 8 9 10 11 | func main() { var a int32 = 10 var b int64 = 3 //b = a //不支持隐式转换,报错Cannot use 'a' (type int32) as type int64 //b = int64(a) //显式转换就可以了 var c float32 c = float32(a) / float32(b) //需要转换 var d = float32(a) / float32(b) //这个时候d可以不需要声明类型 var e = c + float32(b) fmt.Println(c, d) } |
六、总结
切片(slice)、范围(range)、集合Map、递归函数基本上跟其他大部分语言都差不多。切片没有步长(类似python的array[::-1]就倒序),集合Map返回两个值,一个状态值。类型转换必须显式.
【推荐】编程新体验,更懂你的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内存泄漏的七个神坑,你至少踩过三个!