map 使用

package main

import (
    "fmt"
    "strings"
)

func main() {
    item := map[string]string{}
    var cols []map[string]string

    a := "status:success,status:failed"
    b := strings.Split(a, ",")

    for _, vals := range b {
        val := strings.Split(vals, ":")
        item[val[0]] = val[1]
        cols = append(cols, item)

    }

    fmt.Println(cols)
}

//目标输出应该是[map[status:success] map[status:failed]

//实际输出[map[status:failed] map[status:failed]

很奇怪

共 9 个回复


stevenldj

你的代码无法通过编译,修改如下:

func main() {
    item := map[string]string{}
    var cols []map[string]string
    a := "status:success,status:failed"
    b := strings.Split(a, ",")
    for _, val := range b {
        item[val] = "" // 这里
    }
    cols = append(cols, item)
    fmt.Println(cols)
}

输出:

[map[status:success: status:failed:]]
# 0

stevewang

你这代码都编译不过,不知道你想做什么。

# 1

stevewang

你的cols里两个对象其实是同一个map,自然输出同样的结果。
我猜测你想要的是:

package main

import (
    "fmt"
    "strings"
)

func main() {
    var cols []map[string]string
    a := "status:success,status:failed"
    b := strings.Split(a, ",")
    for _, vals := range b {
        val := strings.Split(vals, ":")
        cols = append(cols, map[string]string{
            val[0]: val[1],
        })
    }
    fmt.Println(cols)
}
# 3

haroldT

感谢,您的方法很有用,
但是我还是很疑惑我的方法,因为我打印的时候是以下这种情况的

item[val[0]] = val[1]
fmt.Println(item)
cols = append(cols, item)
fmt.Println(cols)

//map[status:success] “item”
//[map[status:success]] “cols”
//map[status:failed] “item”
//[map[status:failed] map[status:failed]] “cols”
明明它第一次就把success的那个map添加到cols了,请问为什么会这样

同一个map指的是地址的问题吗?

# 4

stevewang

map是引用类型的对象。

m1 := make(map[string]string)
m2 := m1

这段代码中,m1和m2都是指向底层的同一个map对象。

# 5

stevenldj

因为你的item在循环外面声明,只分配了一次内存,所以你加入到cols中的元素其实都是同一个item,你任何时候修改itemcols中的元素都跟着变。

变量item可以理解为指针,你加入到cols中的元素 都是指向同一内存地址的指针。

你把item := map[string]string{}放到循环里面就可以了,这样每次都会分配新内存。

# 6

haroldT

感觉要好好刷一遍语法了


package main

import (
    "fmt"
    "strings"
)

func main() {
    var cols []map[string]string
    item := map[string]string{}  //这里声明的话会打印两个一样的map

    a := "status:success,ip:192.168.2.103}, {status:failed,ip:192.168.2.102"
    infoList := strings.Split(a, "}, {")
    for _, vals := range infoList {

        b := strings.Split(vals, ",")
        //item := map[string]string{}  //然而这里声明就能符合预期,
        for _, vals := range b {

            val := strings.Split(vals, ":")
            item[val[0]] = val[1]
        }
        cols = append(cols, item)

    }
    fmt.Println(cols)
}

明白了,感谢两位

# 7

wy3148

简单的一句话就是 map的key 是唯一的,是不会重复的

# 8