Go map存在重复的键

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

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.

huangapple
  • 本文由 发表于 2016年12月9日 23:53:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/41064208.html
匿名

发表评论

匿名网友

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

确定