MENU

Go语言两道容易踩坑的切片Map题

October 31, 2020 • 技术分享

说明

只做备份,主要是第二题很有趣。和Java中的思想不太一致。

  1. 写一个程序,统计一个字符串中每个单词出现的次数。比如:”how do you do”中how=1 do=2 you=1。
  2. 观察下面代码,写出最终的打印结果。
func main() {
    type Map map[string][]int
    m := make(Map)
    s := []int{1, 2}
    s = append(s, 3)
    fmt.Printf("%+v\n", s)
    m["q1mi"] = s
    s = append(s[:1], s[2:]...)
    fmt.Printf("%+v\n", s)
    fmt.Printf("%+v\n", m["q1mi"])
}

题解

这里是我的题解,欢迎交流

func main(){
    // 写一个程序,统计一个字符串中每个单词出现的次数
    findStr := "how do you do"
    split := strings.Split(findStr, " ")
    fmt.Println(split, len(split), cap(split))
    resultMap := make(map[string]int)
    for _, i := range split {
        v, ok := resultMap[i]
        if !ok {
            resultMap[i] = 1
        } else {
            resultMap[i] = v + 1
        }
    }
    fmt.Println(resultMap)
    
    // 观察下面的结果
    type Map map[string][]int
    m := make(Map)
    s := []int{1, 2}
    s = append(s, 3, 4, 5, 6, 7)
    fmt.Printf("%+v\n", s)
    m["s"] = s
    // 删除索引0到5的元素,即只剩下最后一个元素。Go切片删除元素的第二个参数为需要删除的索引1,所以这里要-1
    s = append(s[:0], s[len(s)-1:]...)
    
    fmt.Printf("%+v %p %+v %+v\n", s, s, len(s), cap(s))
    // 因为切片是引用类型,所以所有的操作都是底层的同一组数据,也就是刚开始定义的s。
    // 还有一个点,在s变量被追加1个元素3之后,就把这个切片的容量赋值给了map,当时容量是3,那么以后怎么搞这个变量s,对于map来说,它只会受到前3个元素的影响,3个元素之后的变化,m是不再受到影响。
    fmt.Printf("%+v %p\n", m["s"], m["s"])
}

控制台输出如下,注意第三行和第五行的切片实际内容。结合上面代码的注释就更能理解元素之后的变化不再受到影响这句话。

[how do you do] 4 4
map[do:2 how:1 you:1]
[1 2 3 4 5 6 7] 7
[7] 0xc0000122c0 1 8
[7 2 3 4 5 6 7] 0xc0000122c0
Last Modified: November 6, 2020
ArchivesQR Code
QR Code for this page
Tipping QR Code