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: ----------
%v
", tcmap)
buf := make([]byte, 1024)
buf[0] = 'a'//0x61
buf[1] = 'd'//0x64
buf[2] = 'c'//0x63
fmt.Printf("Received: ---------
%v
", string(buf[0:3]))
fmt.Printf("Compare hex:-------
|%x| |%x|
", buf[0:3], "adc")
// Get the first field from the message
testname := strings.Split(strings.Trim(string(buf), " "), " ")[0]
fmt.Printf("Test Name: |%v|
", testname)
// Does the key exist in the map?
if t, ok := tcmap[testname]; ok {
fmt.Printf("Test found: %v
", t)
} else {
fmt.Printf("Test NOT found
")
}
// Add testname to map, does it replace existing?
tcmap[testname] = TestCase{Test: "/foo"}
fmt.Printf("
MAP: ---------
%v
", tcmap)
fmt.Printf("KEY adc:---------
%v
", tcmap["adc"])
for k,v := range tcmap {
fmt.Printf("%v: %v
", 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 }
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.
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.