为何(json.Decoder).Decode需接收下一字节后才返回字符串结果?
这个现象的核心原因是Go标准库json.Decoder对不同类型的JSON值采用了不同的结束判定逻辑:
复合类型(对象、数组)的判定逻辑
对象、数组这类复合值有明确的闭合标记(}或]),当解码器读取到对应闭合标记时,即可确定当前JSON值已完整,无需等待后续字节,直接完成解码并返回结果。这就是第一个测试用例{"foo":"bar"}能正常返回的原因——解码器读到}后立即确认对象完整,结束解码流程。基本类型(字符串、数字等)的判定逻辑
字符串、数字、布尔值、null这类基本类型没有明确的“结束标记”,解码器需要读取到不属于当前值的字符(比如下一个JSON值的起始字符、非空白分隔符),或者收到流的EOF信号,才能确定当前值已完整。
对于字符串来说:
当解码器读取到结束的"后,它无法仅凭这个"就确定字符串已结束——因为JSON允许字符串后跟随空白字符(空格、换行、制表符等),而空白字符之后可能还有其他JSON值。如果流未关闭且没有后续字节,解码器会持续阻塞等待,直到有更多数据到来或超时,这就是第二个测试用例"hello"出现超时的原因。
第三个测试用例"hello"{中,解码器在读取到"后,紧接着读到了{(不属于字符串的字符),此时它能确定前面的字符串是一个完整的JSON值,于是尝试将其解码为Message类型,自然返回“无法将字符串解码为结构体”的错误。
即使将目标类型改为string,解码器同样需要等到后续字节或EOF才能确认字符串完整——所以仅传入"hello"且不关闭流的情况下,依然会超时;只有当后续有其他字节或流被关闭时,解码器才会确认字符串完整,返回解码成功的结果。
内容的提问来源于stack exchange,提问作者Sam Herrmann

