在使用bitly的go-simplejson时,在simplejson.Json文字中显示未导出字段'data'的隐式分配

When I use like &simplejson.Json{v} (v is a interface read from file and it's actual data structure is map[string]interface{}), then show this error. Details:

A json file named abcd

{
    "pids": [
        { 
            "pid": 168043, 
            "target_regions": [
                40, 
                25, 
                43, 
                299, 
                240
            ]
         },
        { 
            "pid": 168044, 
            "target_regions": [
                63, 
                65,
                68
            ]
        }
    ]

}

And the go file is

package main    

import (
    "fmt"
    "io/ioutil"    

    sjson "github.com/bitly/go-simplejson"
)    

type pidInfo struct {
    Pid           uint64   `json:"pid"`
    TargetRegions []uint32 `json:"target_regions"`
}    

type pidUnitInfo struct {
    Pid2Info map[uint64]*pidInfo
}    

func build() error {
    content, _ := ioutil.ReadFile("./abcd")
    json, err := sjson.NewJson(content)
    if err != nil {
        return err
    }
    newPidUnitInfo(json)
    return nil
}    

func newPidUnitInfo(json *sjson.Json) (*pidUnitInfo, error) {
    newInfo := new(pidUnitInfo)
    newInfo.buildPid2Info(json)
    return nil, nil
}    

func (pui *pidUnitInfo) buildPid2Info(json *sjson.Json) error {
    raw, ok := json.CheckGet("pids")
    if !ok {
        return fmt.Errorf("not found json key %v", "pids")
    }
    pids, err := raw.Array()
    if err != nil {
        return err
    }
    pui.Pid2Info = make(map[uint64]*pidInfo, len(pids))
    for _, v := range pids {
        fmt.Println(v)
        m := &sjson.Json{v}
        fmt.Println(m)
    }
    return nil
}    

func main() {
    build()
}

When I execute it, show implicit assignment of unexported field 'data' in simplejson.Json literal at this line m := &sjson.Json{v}.

This line:

m := &sjson.Json{v}

Tries to create a value (and take the address) of the struct type Json from package go-simplejson. The type declaration is:

type Json struct {
    data interface{}
}

It has one field: data which is unexported. That means packages other than go-simplejson cannot refer to this field. When you use a struct literal &sjson.Json{v}, it would try to initialize the Json.data field with value v which is a violation of this. You cannot do this.

The Json type is not designed for you to specify the internal data, it is designed so that the data will be the placeholder of some decoded JSON data (see the NewFromReader() and NewJson() constructor-like functions).

This data field is handled internally by the go-simplejson package, you cannot set it yourself. You may use sjson.New() to obtain a new *Json value which will initialize this data field with an empty map (map[string]interface{}). You may also use Json.Map() method which asserts that data is a map and returns it like that:

js := sjson.New()
m, err := js.Map()
if err != nil {
    // Handle error
}

// Now you have a map of type map[string]interface{}

Or to populate the data inside a Json, you can use its Json.Set() method.