简体   繁体   English

在 golang json.Unmarshal() 在操场上工作/复制粘贴 JSON 但在实际代码中没有

[英]In golang json.Unmarshal() works in playground/copy pasted JSON but not in actual code

I am writing a program in Golang that interfaces with a modified version of the barefoot mapmatching library which returns results in json via netcat.我正在用 Golang 编写一个程序,该程序与修改版的赤脚地图匹配库接口,该库通过 netcat 返回 json 的结果。

My in my actual code json.Unmarshal will only parse the response to the nil value of the struct.我在我的实际代码中json.Unmarshal只会解析对结构的 nil 值的响应。 But if print the json to console (see code snippet below) and copy paste into goplayground it behaves as expected.但是,如果将 json 打印到控制台(请参阅下面的代码片段)并将粘贴复制到 goplayground 中,它的行为将符合预期。

I am wondering if this is an encoding issue that is bypassed when I copy paste from the console as a result.我想知道这是否是我从控制台复制粘贴时绕过的编码问题。

How do I get my code to process the same string as it is received from barefoot as when it is copy pasted from the console?如何让我的代码处理从赤脚接收到的字符串与从控制台复制粘贴时相同的字符串?

Here is the relevant code snippet (structs are identical to goplayground)这是相关的代码片段(结构与 goplayground 相同)

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

and io_func() if relevant (the response is two lines, with a message on the first and a json string on the second)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 ""
    }

}

The io_func function creates and discards a bufio.Reader and data the reader may have buffered. io_func function 创建并丢弃 bufio.Reader 和读取器可能缓冲的数据。 If the application calls io_func more than once, then the application may be discarding data read from the network.如果应用程序多次调用 io_func,则应用程序可能正在丢弃从网络读取的数据。 Fix by creating a single bufio.Reader outside the function and pass that single reader to each invocation of io_func.通过在 function 之外创建单个 bufio.Reader 并将该单个阅读器传递给 io_func 的每个调用来修复。

Always check and handle errors.始终检查和处理错误。 The error returned from any of these functions may point you in the right direction for a fix.这些函数中的任何一个返回的错误都可能为您指明正确的修复方向。

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
}

The application uses newline to terminate the JSON body, but newline is valid whitespace in JSON.应用程序使用换行符来终止 JSON 主体,但换行符是 JSON 中的有效空格。 If the peer includes a newline in the JSON, then the application will read a partial message.如果对等方在 JSON 中包含换行符,则应用程序将读取部分消息。

Following Cerise Limón's advice to properly handle error messages I determined the osm_id value in the JSON was being parsed by json.Unmarshall as number when taking the string from io_func() , although it wasn't doing so when the string was passed in manually in the playground example.按照 Cerise Limón 正确处理错误消息的建议,我确定 JSON 中的osm_id值正在被json.Unmarshall解析为从io_func()获取字符串时的数字,尽管在手动传入字符串时它没有这样做游乐场的例子。 Although I don't understand why this is so I would have picked it up with proper error handling.虽然我不明白为什么会这样,但我会通过适当的错误处理来解决它。

I altered barefoot code to return the osm_id explicitly in inverted commas since, although only ever composed of digits, I only use it as a string.我更改了赤脚代码以用反逗号显式返回osm_id ,因为尽管只由数字组成,但我只将其用作字符串。 It now works as expected.它现在按预期工作。 Equally I could have changed the type in the struct and convert in Go as needed.同样,我可以更改结构中的类型并根据需要在 Go 中进行转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM