2016-12-09 6 views
-3

Ich arbeite an einem kleinen Go-Programm, das eine ASCII-Nachricht über UDP empfängt. Ich möchte das erste Feld in der Nachricht nachsehen und prüfen, ob es in einer Map vorhanden ist. Go denkt, dass der Schlüssel nicht in der Karte existiert, aber es tut es. Ich kann den Schlüssel der Karte hinzufügen und er erstellt einen neuen Eintrag, also habe ich zwei Einträge mit demselben Schlüssel. Ich mache etwas falsch oder ist das ein Fehler?Go Map hat doppelte Schlüssel

EDIT: Ich habe den Test vereinfacht, um die UDP und YAML zu entfernen.

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) 
    } 
} 

Ausgang:

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

Sie sollten alle UDP und andere Sachen entfernen, die nicht mit map zusammenhängen. Versuchen Sie, ein einfaches Codebeispiel bereitzustellen. –

+4

Versuchen Sie, den Wert des Schlüssels in der Karte zu erhalten und vergleichen Sie ihn mit dem Wert von 'testname' - sie können gleich aussehen, aber unterschiedlich sein. Zum Beispiel 'adc' und' ards' - sieht ähnlich aus, hat aber 2 verschiedene Zeichen. Setzen Sie Ihr Codebeispiel auf play.golang.org –

+0

Vielen Dank für die Aktualisierung des Codebeispiels. Aber, 1. du bist checkign hex nicht vom Kartenschlüssel. Versuchen Sie, den Ausdruck des Hexfeldes innerhalb des Bereichs zu verschieben. 2. Ich schätze, das Problem besteht darin, wie Sie den Testnamen erhalten. Versuchen Sie, len (testname) zu drucken - wahrscheinlich sind die 0 Bytes einfach nicht gedruckt, also denken Sie, es ist nur 'adc', aber in Wirklichkeit ist es 'adc \ x0 \ 0 ....' –

Antwort

2

Wie Alexander betont, das Problem ist die Länge zwischen den beiden Tasten sind unterschiedlich. Ein Schlüssel hat die Länge 3 und der andere die Länge von 1024. Die ersten drei Bytes waren gleich und auf dem längeren Schlüssel waren die restlichen Bytes 0x00.

Also die String-Ausgabe der beiden Tasten lassen es erscheinen, die beiden sind identisch, aber das hat mich zum Narren gehalten. Die Länge der Schlüssel war unterschiedlich.

1

Einer der Schlüssel ein Newline hat. Wenn Sie strings.TrimSpace anstelle von strings.Trim verwenden, sehen Sie, dass der abschließende Zeilenumbruch gekürzt wird und kein Duplikat vorhanden ist.

+0

Wenn Sie TrimSpace verwenden, funktioniert es immer noch nicht. Es gibt keine neue Zeile. Das Problem war, dass die Anzahl der Bytes zwischen den beiden Schlüsseln unterschiedlich war. – dangeroushobo

+0

Ja, das stimmt ... Upvoted deine Antwort :) (TrimSpace _did_ Arbeit für mich ... vielleicht war es ein Zufall, dass die zusätzlichen Bytes in meinen Testläufen Zeilenumbrüche waren) –