从地图中获取值时出现意外值。

huangapple go评论93阅读模式
英文:

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,我不希望handlernil

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

英文:

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 strings, 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])

huangapple
  • 本文由 发表于 2016年1月16日 15:24:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/34824590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定