Related: https://stackoverflow.com/a/78662958/3768429
On Monday 16 December 2013 at 19:37:30 UTC+1 Kyle Lemons wrote: > On Sun, Dec 15, 2013 at 2:05 PM, Brian Picciano <bgpic...@gmail.com> > wrote: > >> I'm going to compress my three responses to one. >> >> > What I'm less clear on is exactly what your use case is for encoding >> the it as a string if you're dealing with it exclusively as bytes. I mean, >> if you're using it as both, surely you're making the copy anyway at some >> point. >> >> That's my point, I don't want to use string EVER in my application (I >> have no reason to for this particular one). But with encoding/json I have >> to, because I can't directly get []byte out of it for a JSON string value. >> So I have to convert. >> >> > JSON defines strings to be UTF-8 encoded, and as such is not suitable >> for storing binary data. Encoding an unknown []byte with base64 eliminates >> problems >> >> I think that's a decision the coder should make. If I am worried that my >> binary data can't be encoded into a UTF-8 string then I can encode it into >> hex or base64 or whatever I like. But if I KNOW that my data is coming in >> as a proper JSON string and going out the other end without being changed >> in between there's no reason I should be forced to pay the penalty of four >> extra copies ([]byte -> string (inside encoding/json) -> []byte -> app -> >> string -> []byte (inside encoding/json)). >> > > I assume you've benchmarked this and found that the extra copies are a > bottleneck? If not, don't assume that they are without some hard data, > especially if you're doing a lot of I/O (as I would expect of a networked > service). The JSON library does string/[]byte and []byte/string > conversions itself in some places. > > >> > If it's textual data, then string is the correct type. >> >> That's true if I am actually interacting with the data. If I'm just >> carrying the data along and spitting it back out somewhere else than I >> don't really care what it is, and what I really need to optimize for is >> speed and memory. Four copies aren't helping. >> >> > Alternatively you can make your own type that implements MarshalJSON >> and UnmarshalJSON. >> >> The problem with doing this (and the RawMessage) is that you skip the >> unicode (un)escaping step which encoding/json does for strings (internally, >> it actually does it while they're still []byte, so it's pretty trivial to >> have it do it for []byte fields too). I could just pass along the []byte >> untouched, with the backslashes an all still in there, and send it out the >> other end as a JSON string and no-one would be any wiser. But what if that >> other end isn't JSON? What if it''s some custom binary interface? They're >> going to be receiving different data than was passed in. >> > > The implementations are probably pretty easy to write: `js, err := > json.Marshal(string(b))` etc. > > >> On Sun, Dec 15, 2013 at 7:32 AM, egon <egon...@gmail.com> wrote: >> >>> You can use: >>> >>> type MyStruct struct { >>> A, B json.RawMessage >>> } >>> >>> json.RawMessage is defined as type RawMessage byte[]. Alternatively you >>> can make your own type that implements MarshalJSON and UnmarshalJSON. >>> >>> The reason it does b64, is that it is "the correct way" to represent >>> byte array in a json. In other words by default it is safe, but you can >>> override the behavior by using RawMessage or a custom Marshaler. >>> >>> +egon >>> >>> On Saturday, December 14, 2013 10:25:18 PM UTC+2, Brian Picciano wrote: >>>> >>>> I'm sorry if this has been brought up already, I haven't been able to >>>> find anything on it in my searching. I also know this would be a fairly >>>> significant change and would break backwards compatibility, but it is a >>>> fairly annoying "feature" that I think is more of a hindrance than a help. >>>> >>>> Basically the current behavior is that if you have a struct with a >>>> []byte field that you pass into the json marshaler, it will represent that >>>> in the output json string as the base64 encoded version of what you put >>>> in, >>>> and if you're unmarshaling into a []byte it will try to base64 decode the >>>> json string first. I can understand why this might be thought to be "the >>>> right way", since it forces you to use string as a string and raw binary >>>> data as []byte. But it's a bit presumptuous to assume that there is no >>>> legitimate reason anyone should pass a string through to a []byte and work >>>> with them that way. >>>> >>>> Currently, if I want my destination struct to be something like: >>>> >>>> type MyStruct struct { >>>> A, B []byte >>>> } >>>> >>>> And have that be filled by the json string: `{"A":"foo","B":"bar"}`, >>>> then I would first have to make a temporary struct like: >>>> >>>> type MyStructStr struct { >>>> A, B string >>>> } >>>> >>>> And copy/convert each field over individually. Same goes if I want to >>>> convert from MyStruct back into json. This adds a lot of extra code and >>>> data copies. In encoding/json the data is initially passed in and >>>> (un)quoted as []byte, where it is then converted to string. So now I'm >>>> converting back to []byte. This is unnecessary and unoptimizes for the >>>> common case. >>>> >>>> I've hacked a version of encoding/json where I took out the b64 stuff. >>>> It works just fine and is actually less code than it used to be. So >>>> there's >>>> no technical reason it has to stay (to my knowledge). Again, I know this >>>> probably won't make it in for anything in versions 1.*, but for 2 I think >>>> it should be considered. Also, if this is the wrong place to post this >>>> please let me know, I'll happily move it. >>>> >>>> >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/514e9aeb-b08b-4dc5-9184-fb405758381fn%40googlegroups.com.