String 从映射中获取值时出现意外值

String 从映射中获取值时出现意外值,string,dictionary,go,slice,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)), ...

我有一个这样的结构:

type Magni struct {
    ...
    Handlers map[string]func(*Message)
    ...
}
我有一个函数来创建结构的新实例:

func New(nick, user, real string) *Magni {
    return &Magni{
        ...
        Handlers: make(map[string]func(*Message)),
        ...
    }
}
但是我无法从
处理程序
映射中使用键
“hey”
获取某些内容。当
“hey”
位于变量中时,只有我自己键入它才能工作。这是结构
Magni
的方法,
m
是指向结构
Magni
的指针:

handler := m.Handlers[cmd[3][1:]] // cmd[3][1:] contains string "hey"
handler2 := m.Handlers["hey"]
出于某种原因,
handler
的值是
nil
,而
handler2
的值是
0x401310
,基本上我不希望
handler
nil


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

基于变量的值获取值有效:

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]
字符串
本身,但是如果你像
cmd[3][1:///code>那样分割它,它将切断第一个字符(或者更准确地说:从它的UTF-8编码序列中的第一个字节,
字符串的内存表示形式,但是
的字符是“hey”
一对一地映射到字节),因此它将是
“ey”
,您在映射中找不到任何相关值,当然:

cmd = []string{"1", "2", "3", "hey"}
fmt.Println(m[cmd[3][1:]]) // NOT FOUND (empty string - zero value)
试穿这些衣服

如果
cmd[3]
“嘿”
,则无需对其进行切片,只需将其用作键即可

编辑:您声明
cmd[3]
包含
字符串
“:嘿”
。如果可以的话,它也会起作用:

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

fmt.Println([]byte(":hey")) // Prints [58 104 101 121]
打印
cmd[3]
以验证:

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


修剪绳子可以解决这个问题

strings.TrimSpace(cmd[3])

实际上
cmd[3]
是字符串
:hey
所以
cmd[3][1://code>是
hey
@StianOK那么你的
cmd[3]
不是
字符串
”:hey
。请参见编辑以验证它。
strings.TrimSpace(cmd[3])