В golang json.Unmarshal () работает на детской площадке / копирование вставлено JSON, но не в реальном коде - PullRequest
0 голосов
/ 30 октября 2019

Я пишу программу на Голанге, которая взаимодействует с модифицированной версией библиотеки barefoot mapmatching, которая возвращает результаты в формате json через netcat.

My в моем действительном коде json.Unmarshal willтолько анализируйте ответ на нулевое значение структуры. Но если вы распечатываете json на консоль (см. Фрагмент кода ниже) и копируете вставку в goplayground , она ведет себя как положено.

Мне интересно, если это проблема с кодировкой, которая обходит, когда я копирую вставить из консоли в результате.

Как я могу получить мой код для обработки той же строки, как она полученаиз босиком, как при копировании с консоли?

Здесь приведен соответствующий фрагмент кода (структуры идентичны goplayground)

body := io_func(conn, cmd)
    var obvs []Json_out
    json.Unmarshal([]byte(body), &obvs)
    fmt.Println(body)
    fmt.Println(obvs)

и io_func(), если необходимо (ответдве строки, с сообщением в первой и строкой json во второй)

func io_func(conn net.Conn, cmd string) string {
    fmt.Fprintf(conn, cmd+"\n")
    r := bufio.NewReader(conn)
    header, _ := r.ReadString('\n')
    if header == "SUCCESS\n" {
        resp, _ := r.ReadString('\n')
    return resp
    } else {
        return ""
    }

}

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Следуя совету Cerise Limón по правильной обработке сообщений об ошибках, я определил, что значение osm_id в JSON анализировалось json.Unmarshall как число при получении строки из io_func(), хотя это не происходило, когда строкабыл передан вручную на примере детской площадки. Хотя я не понимаю, почему это так, я бы подобрал его с правильной обработкой ошибок.

Я изменил код босиком, чтобы возвращать osm_id в явном виде в кавычках, хотя только когда-либо состоял из цифр,Я использую это только как строку. Теперь он работает как положено. Точно так же я мог бы изменить тип в структуре и конвертировать в Go по мере необходимости.

0 голосов
/ 30 октября 2019

Функция io_func создает и удаляет bufio.Reader и данные, которые читатель мог буферизовать. Если приложение вызывает io_func более одного раза, приложение может отбрасывать данные, считанные из сети. Исправьте, создав отдельный bufio.Reader вне функции и передавайте этот отдельный читатель каждому вызову io_func.

Всегда проверяйте и обрабатывайте ошибки. Ошибка, возвращаемая любой из этих функций, может указывать правильное направление для исправления.

func io_func(r *bufio.Reader, conn net.Conn, cmd string) (string, error) {
    fmt.Fprintf(conn, cmd+"\n")
    header, err := r.ReadString('\n')
    if err != nil {
        return "", err
    }
    if header == "SUCCESS\n" {
        return r.ReadString('\n')
    }
    return "", nil
}


...

r := bufio.NewReader(conn)

body, err := io_func(r, conn, cmd)
if err != nil {
    // handle error
}
var obvs []Json_out
err = json.Unmarshal([]byte(body), &obvs)
if err != nil {
    // handle error
}
fmt.Println(body)
fmt.Println(obvs)

// read next 
body, err = io_func(r, conn, cmd)
if err != nil {
    // handle error
}

Приложение использует новую строку для завершения тела JSON, но новая строка является допустимым пробелом в JSON. Если одноранговый узел включает в JSON символ новой строки, приложение будет читать частичное сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...