英文:
Go map has duplicate keys
问题
我正在处理一个小的Go程序,该程序通过UDP接收ASCII消息。我想查找消息中的第一个字段,并查看它是否存在于一个映射中。Go认为映射中不存在该键,但实际上存在。我可以将该键添加到映射中,并创建一个新条目,这样就会有两个具有相同键的条目。我是做错了什么还是这是一个bug?
编辑:
我已经简化了测试,去除了UDP和YAML。
package main
import (
"fmt"
"strings"
)
type TestCase struct {
Test string
Result string
}
func main() {
tcmap := make(map[string]TestCase)
tcmap["adc"] = TestCase{Test: "/bar"}
fmt.Printf("TestMap: ----------\n%v\n\n", tcmap)
buf := make([]byte, 1024)
buf[0] = 'a' //0x61
buf[1] = 'd' //0x64
buf[2] = 'c' //0x63
fmt.Printf("Received: ---------\n%v\n\n", string(buf[0:3]))
fmt.Printf("Compare hex:-------\n|%x| |%x|\n\n", buf[0:3], "adc")
// Get the first field from the message
testname := strings.Split(strings.Trim(string(buf), " "), " ")[0]
fmt.Printf("Test Name: |%v|\n", testname)
// Does the key exist in the map?
if t, ok := tcmap[testname]; ok {
fmt.Printf("Test found: %v\n", t)
} else {
fmt.Printf("Test NOT found\n")
}
// Add testname to map, does it replace existing?
tcmap[testname] = TestCase{Test: "/foo"}
fmt.Printf("\nMAP: ---------\n%v\n\n", tcmap)
fmt.Printf("KEY adc:---------\n%v\n\n", tcmap["adc"])
for k, v := range tcmap {
fmt.Printf("%v: %v\n", k, v)
}
}
输出:
TestMap: ----------
map[adc:{/bar }]
Received: ---------
adc
Compare hex:-------
|616463| |616463|
Test Name: |adc|
Test NOT found
MAP: ---------
map[adc:{/bar } adc:{/foo }]
KEY adc:---------
{/bar }
adc: {/bar }
adc: {/foo }
英文:
I'm working on a small Go program that receives an ascii message over UDP. I want to look up the first field in the message and see if it exist in a map. Go thinks the key does not exist in the map but it does. I can add the key to the map and it creates a new entry, so I have two entries with the same key. I'm I doing something wrong or is this a bug?
EDIT:
I've simplified the test down to remove the UDP and YAML.
https://play.golang.org/p/2Bg8UjhfWC
package main
import (
"fmt"
"strings"
)
type TestCase struct {
Test string
Result string
}
func main() {
tcmap := make(map[string]TestCase)
tcmap["adc"] = TestCase{Test: "/bar"}
fmt.Printf("TestMap: ----------\n%v\n\n", tcmap)
buf := make([]byte, 1024)
buf[0] = 'a'//0x61
buf[1] = 'd'//0x64
buf[2] = 'c'//0x63
fmt.Printf("Received: ---------\n%v\n\n", string(buf[0:3]))
fmt.Printf("Compare hex:-------\n|%x| |%x|\n\n", buf[0:3], "adc")
// Get the first field from the message
testname := strings.Split(strings.Trim(string(buf), " "), " ")[0]
fmt.Printf("Test Name: |%v|\n", testname)
// Does the key exist in the map?
if t, ok := tcmap[testname]; ok {
fmt.Printf("Test found: %v\n", t)
} else {
fmt.Printf("Test NOT found\n")
}
// Add testname to map, does it replace existing?
tcmap[testname] = TestCase{Test: "/foo"}
fmt.Printf("\nMAP: ---------\n%v\n\n", tcmap)
fmt.Printf("KEY adc:---------\n%v\n\n", tcmap["adc"])
for k,v := range tcmap {
fmt.Printf("%v: %v\n", k, v)
}
}
Output:
TestMap: ----------
map[adc:{/bar }]
Received: ---------
adc
Compare hex:-------
|616463| |616463|
Test Name: |adc|
Test NOT found
MAP: ---------
map[adc:{/bar } adc:{/foo }]
KEY adc:---------
{/bar }
adc: {/bar }
adc: {/foo }
答案1
得分: 3
如亚历山大所指出的,问题在于两个密钥之间的长度不同。一个密钥的长度为3,而另一个密钥的长度为1024。前三个字节是相同的,而在较长的密钥上,剩余的字节都是0x00。
因此,这两个密钥的字符串输出使它们看起来是相同的,但这欺骗了我。密钥的长度是不同的。
英文:
As pointed out by Alexander, the issue is the length between the two keys are different. One key has the length of 3 and the other has the length of 1024. The first three bytes were the same and on the longer key the remaining bytes were 0x00.
So the string output of the two keys make it appear the two are identical, but this was fooling me. The length of the keys was different.
答案2
得分: 2
其中一个键有一个尾随的换行符。如果你使用strings.TrimSpace
而不是strings.Trim
,你会发现尾随的换行符被修剪掉了,而且没有重复。
英文:
One of the keys has a trailing newline. If you use strings.TrimSpace
instead of strings.Trim
you'll see that the trailing newline is trimmed and there is no duplicate.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论