英文:
Unexpected value when getting value from a map
问题
所以我有一个像这样的结构体:
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"
时,我无法得到任何东西,只有当我自己输入时才有效。这是结构体Magni
的一个方法,其中m
是指向结构体Magni
的指针:
handler := m.Handlers[cmd[3][1:]] // cmd[3][1:] 包含字符串 "hey"
handler2 := m.Handlers["hey"]
由于某种原因,handler
的值是nil
,而handler2
的值是0x401310
,我不希望handler
是nil
。
我是做错了什么还是这是预期的行为?
英文:
So I have a struct like this:
type Magni struct {
...
Handlers map[string]func(*Message)
...
}
And I have a function to create a new instance of the struct:
func New(nick, user, real string) *Magni {
return &Magni{
...
Handlers: make(map[string]func(*Message)),
...
}
}
But I can't get something from the Handlers
map with the key "hey"
when "hey"
is in a variable, it only works if I type it myself. Here is a method of the struct Magni
and m
is a pointer to the struct Magni
:
handler := m.Handlers[cmd[3][1:]] // cmd[3][1:] contains string "hey"
handler2 := m.Handlers["hey"]
For some reason, the value of handler
is nil
and the value of handler2
is 0x401310
, basically I am not expecting handler
to be nil
.
Am I doing something wrong or is this the expected behavior?
答案1
得分: 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:]
这样对其进行切片,它将去掉第一个字符(或者更准确地说,去掉其UTF-8编码序列的第一个字节,string
的内存表示形式,但是"hey"
的字符与字节一一对应),因此它将变为"ey"
,在映射中当然找不到任何关联的值:
cmd = []string{"1", "2", "3", "hey"}
fmt.Println(m[cmd[3][1:]]) // NOT FOUND(空字符串 - 零值)
你可以在Go Playground上尝试这些代码。
如果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")) // 打印 [58 104 101 121]
打印cmd[3]
以进行验证:
fmt.Println([]byte(cmd[3]))
你还可以将其与你认为的string
进行比较,但这只会告诉你它们是否相等(并不会告诉你差异在哪里):
fmt.Println(cmd[3] == ":hey", cmd[3][1:] == "hey")
英文:
Getting the value based on the value of a variable works:
m := map[string]string{"hey": "found"}
fmt.Println(m["hey"]) // found
cmd := []string{"1", "2", "3", "hey"}
fmt.Println(m[cmd[3]]) // found
It even works if the variable is of string
type and you slice its value, e.g.:
cmd = []string{"1", "2", "3", "Hhey"}
fmt.Println(m[cmd[3][1:]]) // found
You issue is most likely cmd[3]
is the string
"hey"
itself, but if you slice it like cmd[3][1:]
, it will cut off the first character (or to be precise: the first byte from its UTF-8 encoding sequence, the memory representation of string
s, but the characters of "hey"
map to bytes one-to-one), so it will be "ey"
, for which you will not find any associated value in the map of course:
cmd = []string{"1", "2", "3", "hey"}
fmt.Println(m[cmd[3][1:]]) // NOT FOUND (empty string - zero value)
Try these on the Go Playground.
If cmd[3]
is "hey"
, no need to slice it, just use it as a key.
Edit: You claim cmd[3]
contains the string
":hey"
. If it would, it would also work:
cmd = []string{"1", "2", "3", ":hey"}
fmt.Println(m[cmd[3][1:]]) // found
So your cmd[3]
is not what you think it is. It may contain 0
bytes or unprintable characters. Print its bytes to verify. For example bytes of the string
":hey"
are: [58 104 101 121]
fmt.Println([]byte(":hey")) // Prints [58 104 101 121]
Print your cmd[3]
to verify:
fmt.Println([]byte(cmd[3]))
You could also compare it to the strings
you think it is, but that will only tell you whether they are equal (and won't tell you where the difference is):
fmt.Println(cmd[3] == ":hey", cmd[3][1:] == "hey")
答案2
得分: 0
修剪字符串可以解决问题。
strings.TrimSpace(cmd[3])
英文:
Trimming the string solves the problem.
strings.TrimSpace(cmd[3])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论