Json marshal - unsupported type: map[int]string

10,017 views
Skip to first unread message

bsr

unread,
Jul 2, 2012, 10:14:10 AM7/2/12
to golan...@googlegroups.com

Hello,
When I marshal the below struct (in fact, part/field of another struct), I get error

json: unsupported type: map[int]string

type Header struct {
M map[int]string
}

But the below works.

type Header struct {
M string
}

I thought JSON can Marshal any exported type.

thanks

chris dollin

unread,
Jul 2, 2012, 10:22:51 AM7/2/12
to bsr, golan...@googlegroups.com
On 2 July 2012 15:14, bsr <bsr...@gmail.com> wrote:
>
> Hello,
> When I marshal the below struct (in fact, part/field of another struct), I
> get error
>
> json: unsupported type: map[int]string

JSON objects only permit string key: http://www.json.org/

Chris

--
Chris "allusive" Dollin

DisposaBoy

unread,
Jul 2, 2012, 10:26:40 AM7/2/12
to golan...@googlegroups.com
Those two structs are entirely different. You get an error on the former because JSON doesn't support integer keys, only strings. see: http://json.org/

 

bsr

unread,
Jul 2, 2012, 10:33:54 AM7/2/12
to golan...@googlegroups.com
It is amazing how quickly I got the response from you guys! Fell like SO .. thanks.

I was using map[TMessageType]string

where TMessageType is 
type TMessageType int


const (
_ TMessageType = iota
ALERT
ERROR
SUCCESS
INFO
)

so, I may have to define 4 string constants instead. Thanks.

chris dollin

unread,
Jul 2, 2012, 10:40:53 AM7/2/12
to bsr, golan...@googlegroups.com
On 2 July 2012 15:33, bsr <bsr...@gmail.com> wrote:
> It is amazing how quickly I got the response from you guys! Fell like SO ..
> thanks.
>
> I was using map[TMessageType]string
>
> where TMessageType is
> type TMessageType int
>
>
> const (
> _ TMessageType = iota
> ALERT
> ERROR
> SUCCESS
> INFO
> )
>
> so, I may have to define 4 string constants instead. Thanks.

Or

type MyMap map[TMessageType]string

and make that type satisfy the json.Marshaler interface.

bsr

unread,
Jul 2, 2012, 10:57:47 AM7/2/12
to golan...@googlegroups.com, bsr
thanks Chris.

What is the best way to have a set of string constants. This way, I can enforce keys as one of the members of the group. I was thinking something line

const TMessageType = [string]{"ALERT", "ERROR", "SUCCESS", "INFO"}
or
const TMessageType = [4]string{"ALERT", "ERROR", "SUCCESS", "INFO"}

gives error. I am missing on the syntax or slice can't be const?.. thanks

bsr

unread,
Jul 2, 2012, 11:05:26 AM7/2/12
to golan...@googlegroups.com, bsr
Never mind. I saw a response from Ian about this.

Being precise, passing an array to a function copies the array anyhow. 
Your argument is a reason to not have const slices.  That said, there 
are very similar arguments against const arrays: what happens if you 
take the address?  What happens if you make a slice? 

Spec also says the same.

I guess I may just make it as var instead of const.

chris dollin

unread,
Jul 2, 2012, 11:06:07 AM7/2/12
to bsr, golan...@googlegroups.com
On 2 July 2012 15:57, bsr <bsr...@gmail.com> wrote:
>
> What is the best way to have a set of string constants. This way, I can
> enforce keys as one of the members of the group. I was thinking something
> line
>
> const TMessageType = [string]{"ALERT", "ERROR", "SUCCESS", "INFO"}

Bad syntax: []string, not [string]. But ...

> or
> const TMessageType = [4]string{"ALERT", "ERROR", "SUCCESS", "INFO"}
> gives error. I am missing on the syntax or slice can't be const?.. thanks

... consts can only be numbers, booleans, and strings, not arrays or slices.

You can name the individual strings.

bsr

unread,
Jul 2, 2012, 11:28:20 AM7/2/12
to golan...@googlegroups.com, bsr
Sorry for keep coming back to the same subject. 
So how would you enforce a condition, which detects whether a function parameter (or a type) can only have a set of values statically (at compile time.
)


Only way I could think about defining a struct with unexported field, and having a constructor which validates the constraint. Is there an easier (as the validation method can have ugly  if/else conditions)

thanks.

DisposaBoy

unread,
Jul 2, 2012, 12:01:34 PM7/2/12
to golan...@googlegroups.com, bsr


On Monday, July 2, 2012 4:28:20 PM UTC+1, bsr wrote:
Sorry for keep coming back to the same subject. 
So how would you enforce a condition, which detects whether a function parameter (or a type) can only have a set of values statically (at compile time.
)


Only way I could think about defining a struct with unexported field, and having a constructor which validates the constraint. Is there an easier (as the validation method can have ugly  if/else conditions)

thanks.


one simple way is to use a type somewhat like you were doing before but instead of using an int, just use a string as the underlying type

 

bsr

unread,
Jul 2, 2012, 12:20:22 PM7/2/12
to golan...@googlegroups.com, bsr
But this works though 

so the allowed values are not enforced, being the key is in effect a string.

Xing Xing

unread,
Jul 2, 2012, 10:29:55 PM7/2/12
to golan...@googlegroups.com
于 Mon, 2 Jul 2012 09:20:22 -0700 (PDT)
bsr <bsr...@gmail.com> 写道:

> But this works though
> http://play.golang.org/p/tlqO3qwjtt
>
> so the allowed values are not enforced, being the key is in effect a
> string.
>

I've committed a patch for this: http://codereview.appspot.com/6338067/
It works fine. But When I was thinking about that, I found some issues
with this patch:

1. The json.Marshal could treat the map[int]T, how about the
json.Unmarshal?

2. json.Marshal treat the map[int]T into json form "{string:T}".
Strange, isn't it?

3. If it count treat a numeric keys of map, shall we treat it in a more
general way? Eg. type of map's key can convert into string, or it has a
method String().
Reply all
Reply to author
Forward
0 new messages