package main import "fmt" func main() { // 定义一个长度为2的切片,其元素的数据类型为string var slice = make([]string, 2) // 等价于:var slice []string = make([]string, 2) slice[0] = "m" slice[1] = "a" // 也可以在定义切片时直接设置元素,这样就不需要使用make()函数 // var slice = []string{"m", "a"} fmt.Printf("slice = %+v \n", slice) // slice = [m a] fmt.Printf("slice长度 = %+v \n", len(slice)) // slice长度 = 2 // 切片追加元素 slice = append(slice, "n") slice = append(slice, "o") slice = append(slice, "n") slice = append(slice, "g") fmt.Printf("slice = %+v \n", slice) // slice = [m a n o n g] fmt.Printf("slice长度 = %+v \n", len(slice)) // slice长度 = 6 str := "" // 遍历切片,使用『for index, value := range 切片』方式,如果不需要使用索引编号“index”可以将其改为“_” for index, value := range slice { fmt.Printf("第%d个字母:%s \n", index, value) // 第0个字母:m // 第1个字母:a // 第2个字母:n // 第3个字母:o // 第4个字母:n // 第5个字母:g str += value } fmt.Printf("str = %+v \n", str) // str = manong } // ========== 总结 ========== // // 1、切片可以粗略理解为可动态改变长度的数组(注:数组在定义时必须指定长度,且无法修改长度)。 // 2、遍历切片和遍历数组的方式是一样的,都可以通过『for index, value := range slice』来遍历, // 如果不需要使用索引编号“index”可以将其改为“_”。 // 3、切片判空只能用len(slice)是否为0来判断,不能用slice是否为nil来判断。 // 4、切片与切片之间不能比较,即不能用==来判断两个切片是否相等。
package main import ( "fmt" ) type Human struct { Name string Sex string Birth int } func main() { slice := []Human{ {Name: "张三", Sex: "男", Birth: 2003}, {Name: "李四", Sex: "女", Birth: 2004}, {Name: "王五", Sex: "男", Birth: 2005}, } m := map[int]*Human{} // 遍历切片元素 for index, value := range slice { m[index] = &value } // 重要说明:上面的遍历结构体切片元素代码是有问题的,value是临时变量,它保存的是结构体的值,而不是指针, // 并且在整个遍历过程中会一直复用,即每轮循环“m[index] = &value”都是在保存一个临时变量的指针, // 并不能把slice的数据转存到m里,当执行最后一轮循环时,slice最后一个元素的值会拷贝到value。 fmt.Println(m) // map[0:0xc00010e180 1:0xc00010e180 2:0xc00010e180] // 重要说明:从打印结果可以清楚地看到,m的三个元素是同一个指针。 // 遍历map元素 for index, value := range m { fmt.Printf("map第%d个元素:%s %s %d \n", index, value.Name, value.Sex, value.Birth) } // map第1个元素:王五 男 2005 // map第2个元素:王五 男 2005 // map第0个元素:王五 男 2005 // 重要说明:由于m的三个元素是同一个指针,所以打印出来的内容是完全一样的。 } // ========== 总结 ========== // // 1、上面代码问题的根源在于slice和m的valueType不一致,slice的valueType是Human,而m的valueType是*Human, // 即一个是结构体,一个是结构体指针。解决问题的办法也很简单,把slice和m的valueType改为相同的即可, // 可以两个都改为Human,或者两个都改为*Human,一般来说建议使用*Human。 // 操作结构体建议使用指针,而不是结构体本身,因为将结构体指针作为参数传递不会发生值拷贝故而效率更高, // 并且也可以避免因为值拷贝导致的稀奇古怪的问题。
Copyright © 2025 码农人生. All Rights Reserved