douxuan1284 2018-11-08 23:57
浏览 16
已采纳

在Go中解组为struct时的奇怪行为

I'm developing a tool that can be implemented to simplify the process of creating simple CRUD operations/endpoints. Since my endpoints don't know what kind of struct they'll be receiving, I've created an interface that users can implement, and return an empty object to be filled.

type ItemFactory interface {
    GenerateEmptyItem() interface{}
}

And the users would implement something like:

type Test struct {
    TestString string `json:"testString"`
    TestInt int `json:"testInt"`
    TestBool bool `json:"testBool"`
}

func (t Test) GenerateEmptyItem() interface{} {
    return Test{}
}

When the Test object gets created, its type is "Test", even though the func returned an interface{}. However, as soon as I try to unmarshal some json of the same format into it, it strips it of its type, and becomes of type "map[string]interface {}".

item := h.ItemFactory.GenerateEmptyItem()

//Prints "Test"
fmt.Printf("%T
", item)

fmt.Println(reflect.TypeOf(item))

err := ConvertRequestBodyIntoObject(r, &item)
if err != nil {...}

//Prints "map[string]interface {}"
fmt.Printf("%T
", item)

Func that unmarshalls item:

func ConvertRequestBodyIntoObject(request *http.Request, object interface{}) error {
    body, err := ioutil.ReadAll(request.Body)
    if err != nil {
        return err
    }

    // Unmarshal body into request object
    err = json.Unmarshal(body, object)
    if err != nil {
        return err
    }

    return nil
}

Any suggestions as to why this happens, or how I can work around it?

Thanks

  • 写回答

1条回答 默认 最新

  • duanchen7036 2018-11-09 01:29
    关注

    Your question lacks an example showing this behavior so I'm just guessing this is what is happening.

    func Generate() interface{} {
        return Test{}
    }
    
    func GeneratePointer() interface{} {
        return &Test{}
    }
    
    func main() {
    
        vi := Generate()
        json.Unmarshal([]byte(`{}`), &vi)
        fmt.Printf("Generate Type: %T
    ", vi)
    
        vp := GeneratePointer()
        json.Unmarshal([]byte(`{}`), vp)
        fmt.Printf("GenerateP Type: %T
    ", vp)
    }
    

    Which outputs:

    Generate Type: map[string]interface {}
    GenerateP Type: *main.Test
    

    I suggest you return a pointer in GenerateEmptyItem() instead of the actual struct value which is demonstrated in the GenerateP() example.

    Playground Example

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥15 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)