从地图获取值时的意外值

时间:2016-01-16 07:24:11

标签: string dictionary go slice

所以我有这样的结构:

type Magni struct {
    ...
    Handlers map[string]func(*Message)
    ...
}

我有一个函数来创建结构的新实例:

func New(nick, user, real string) *Magni {
    return &Magni{
        ...
        Handlers: make(map[string]func(*Message)),
        ...
    }
}

但是当Handlers位于变量中时,我无法使用键"hey""hey"地图获取某些内容,只有在我自己输入时才能生效。这是struct Magni的方法,m是指向struct Magni的指针:

handler := m.Handlers[cmd[3][1:]] // cmd[3][1:] contains string "hey"
handler2 := m.Handlers["hey"]

出于某种原因,handler的值为nilhandler2的值为0x401310,基本上我不期望handlernil {1}}。

我做错了什么或这是预期的行为?

2 个答案:

答案 0 :(得分:1)

根据变量的值获取值:

m := map[string]string{"hey": "found"}
fmt.Println(m["hey"]) // found

cmd := []string{"1", "2", "3", "hey"}
fmt.Println(m[cmd[3]]) // found

如果变量是string类型并且您对其值进行切片,它甚至可以工作,例如:

cmd = []string{"1", "2", "3", "Hhey"}
fmt.Println(m[cmd[3][1:]]) // found

您的问题很可能cmd[3]string "hey"本身,但如果您将其切成cmd[3][1:],它会切断第一个字符(或者是exact:来自其UTF-8编码序列的第一个字节,string的内存表示,但"hey"的字符一对一映射到字节),因此它将是{{1当然,你不会在地图中找到任何相关的值:

"ey"

Go Playground上尝试这些。

如果cmd = []string{"1", "2", "3", "hey"} fmt.Println(m[cmd[3][1:]]) // NOT FOUND (empty string - zero value) cmd[3],则无需对其进行切片,只需将其用作密钥即可。

修改:您声称"hey"包含cmd[3] string。如果可以,它也会起作用:

":hey"

所以你的cmd = []string{"1", "2", "3", ":hey"} fmt.Println(m[cmd[3][1:]]) // found 不是你想象的那样。它可能包含cmd[3]个字节或不可打印的字符。打印其字节以进行验证。例如0 string的字节为:":hey"

[58 104 101 121]

打印您的fmt.Println([]byte(":hey")) // Prints [58 104 101 121] 进行验证:

cmd[3]

您也可以将它与您认为的fmt.Println([]byte(cmd[3])) 进行比较,但这只会告诉您它们是否相等(并且不会告诉您差异在哪里):

strings

答案 1 :(得分:0)

修剪字符串可以解决问题。

virtual