Unmarshall gives an error for nested struct

Hi,

can someone please help me here, when i assign the values through variable it does not work. Unmarshal gives me an error. However when i assign the hard coded value it does work fine. Any specific reason please? is there any other way around to make this work please. i am using nested struct. Below is my sample code. It does work when i assign hard coded value to nested struct.

package main

import (
“encoding/json”
“fmt”
)

type TestConfig struct {
CId string json:"cid"
BSize int json:"bsize"
Number int json:"number"
LHash string json:"lhasg"
MCr string json:"mcr"
LId string json:"lid"
Fr struct {
FrId string json:"frid"
FrAdd string json:"fradd"
} json:"fr"
Ml struct {
MsId string json:"msid"
MsInfo string json:"msinfo"
} json:"ml"
}

func main() {
var a0, a1 int
var a2, a3, a4, a5, a6, a7, a8, a9 string

a0 = 1000
a1 = 10
a2 = "TestOne"
a3 = "TestTwo"
a4 = "TestThree"
a5 = "TestFour"
a6 = "TestFive"
a7 = "TestSix"
a8 = "TestSeven"
a9 = "TestEight"

jsonConfig := []byte(`{"cid"   : a2, 
                       "bsize" : a0,
                       "number": a1,
                           "lhash" : a3,
                       "mcr"   : a4,
                       "lid"   : a5,
                       "fr"    :{"frid":a6,
                       "fradd" :a7},
                       "masl"  :{"msid":a8,
                       "msinfo":a9}}`)
var config TestConfig
err := json.Unmarshal(jsonConfig, &config)
if err != nil {
	panic(err)
}
fmt.Printf("Config: %+v\n", config)

}

In the string

`{"cid"   : a2, 
  "bsize" : a0, 

and so on will the values a2, a0 and more not be replaced with the values of variables with the same name. json.Ummarshall will try to parse it as is.

Hi Johan, I didn’t get you completely. Can you please elaborate bit more but.What mean same name. I have used different variable names like a0…a9.

Hi @jayts can you please pass your thoughts over this. Please

Variables aren’t recognized within a “string literal”. You need the JSON object to be: {"cid":"TestOne","bsize":1000, ... }.

Hi Charles, Actually I don’t want that to take hard coded values. I am passing them from another interface. The values would be dynamic input parameter. In that case how would I have to define that.

If all you’re doing is trying to initialize the TestConfig struct value, then you can just initialize jsonConfig with those values. If your trying to create a JSON object with the configuration information then you can do something like: https://play.golang.org/p/xFyavcEfSwK.

Hi Dattatray,

I don’t have time to post on the forum right now, especially by request, but I took a quick look at it.

It looks like you are having trouble because the JSON is quoted with backquotes (backticks), so the contents of the string literal cannot be handled by the Go compiler as variable names.

There are two kinds of string literals (or literal strings) in Go. One uses double quotes ("), and the other uses backticks (). The first type is called an interpreted string literal. It’s interpreted because it can contain escape sequences (actually, byte values is the term used in the Go Language specification) like \n,\0377, \xff, or \uaaff that are converted into binary (in the case of\n, a single newline replaces the backslash and n).

But when you use backticks, it creates a raw string literal, and nothing is done to the contents of the string. If you want to get yourself into trouble, just insert a single backtick outside of a comment near the beginning of a very long Go program and see what you get from the compiler. Try putting it in the middle of a variable or function name. :smile:

Anyway, to the main point: In your jsonConfig byte slice, you are providing a raw string literal. So there’s no way the compiler will recognize variable names inside of that. It doesn’t look at the characters at all, and accepts the string literal exactly as you wrote it.

One thing you might try is to use the string as a format string to fmt.Sprintf(), with your variable names replaced with a printf verb (%s, %d, or other), and then you can insert the values of the variables into the JSON that way.

I don’t even know if Sprintf() will work on format strings with newlines (I’ve never tried it), and if it doesn’t, then you will need to find another method. I apologize if I steered you in the wrong direction, and I simply don’t have time at the moment to come up with something better. I’m working on client-side web app that doesn’t involve JSON, and my head isn’t in the right space to think about this right now. So good luck with it! (BTW, I’d look for any examples on the net of JSON marshaling and unmarshaling in Go and see if there is an “idiomatic” way of doing it that isn’t idiotic. :grin:

1 Like

Hi Charles, I think this is exactly what I was looking for. I will try this out and let you. Thank you so much!!!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.