2016-12-09 5 views
-3

Я работаю над небольшой программой Go, которая получает сообщение ascii через UDP. Я хочу посмотреть первое поле в сообщении и посмотреть, существует ли оно на карте. Go думает, что ключ не существует на карте, но это так. Я могу добавить ключ к карте и создать новую запись, поэтому у меня есть две записи с одним и тем же ключом. Я делаю что-то неправильно или это ошибка?На карте есть дубликаты ключей

EDIT: Я упростил тест, чтобы удалить UDP и 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) 
    } 
} 

Выход:

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

Вы должны удалить все UDP и другие материалы, не связанные с картой. Попробуйте предоставить простой пример кода. –

+4

Попробуйте получить значение ключа на карте и сравнить его со значением 'testname' - они могут выглядеть одинаково, но быть разными. Например, 'adc' и' аdс' - похожи, но имеют 2 разных символа. Поместите свой образец кода в play.golang.org –

+0

Спасибо за обновление образца кода. Но, в-четвертых, вы не являетесь контрольным шестнадцатеричным ключом карты. попробуйте перенести печать гексагона внутри диапазона. Второй. Я думаю, проблема связана с тем, как вы получаете тестовое имя. Попробуйте напечатать len (testname) - возможно, 0 байтов просто не напечатаны, поэтому вы считаете, что это просто «adc», но на самом деле это «adc \ x0 \ 0 ....» –

ответ

2

Как указал Александр, вопрос заключается в том, что длина между двумя ключами различна. Один ключ имеет длину 3, а другой - длину 1024. Первые три байта были одинаковыми, а на более длинном ключе оставшиеся байты были 0x00.

Таким образом, вывод строки из двух клавиш показывает, что они идентичны, но это меня обманывало. Длина клавиш была иной.

1

Один из ключей имеет символ новой строки. Если вы используете strings.TrimSpace вместо strings.Trim, вы увидите, что завершающая новая строка обрезана, а дубликат отсутствует.

+0

Если вы используете TrimSpace, он все равно не работает. Нет новой строки. Проблема заключалась в том, что количество байтов между двумя ключами было разным. – dangeroushobo

+0

Да, это правда ... поднял ваш ответ :) (TrimSpace _did_ работает для меня ... возможно, это была случайность, что дополнительные байты в моих тестовых прогонах были новыми) –

Смежные вопросы