为了账号安全,请及时绑定邮箱和手机立即绑定

通过引用分配

通过引用分配

Go
四季花海 2022-07-04 16:26:07
我在 Go 中遇到了一个小任务的参考问题。我试图在下面的代码中模仿这个问题。package mainimport (    "encoding/json"    "fmt")type tRes struct {    a string    b interface{}}func get(t string, r interface{}) error {    var res tRes    switch t {    case "string":        res = tRes{            a: "XYZ",            b: "Nobody",        }    case "int":        res = tRes{            a: "XYZ",            b: 10,        }    }    // r = &res.b    j, _ := json.Marshal(res.b)    json.Unmarshal(j, &r)    return nil}func main() {    var b string    get("string", &b)    fmt.Println(b)        var i int    get("int", &i)    fmt.Println(i)}在代码中,get 方法根据类型返回一个值。如果我使用r = &res.b它不起作用而j, _ := json.Marshal(res.b) json.Unmarshal(j, &r)起作用。我不想像在实际代码中那样对一个非常大的对象执行 json marshal 和 unmarshal,我正在调用一个返回大对象的 API。我执行 json unmarshal 来创建主对象,然后将一个子对象(定义为 interface{})分配给响应(可能是不同的类型)作为对我不起作用的参考。
查看完整描述

2 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

目标是b在解组之前设置字段的类型。使用以下代码:


func get(data []byte, r interface{}) error {

    res := struct {

        A string

        B interface{}

    }{

        B: r,

    }

    return json.Unmarshal(data, &res)

}

像这样称呼它:


func main() {

    var b string

    get([]byte(`{"a": "XYZ", "b": "Nobody"}`), &b)

    fmt.Println(b)


    var i int

    get([]byte(`{"a": "XYZ", "b": 10}`), &i)

    fmt.Println(i)

}


查看完整回答
反对 回复 2022-07-04
?
慕的地6264312

TA贡献1817条经验 获得超6个赞

您正在将interface{}值传递给您的get函数。由于它是按值传递的,因此您的r = &res.b赋值将覆盖函数中的值,这对引用中包含的值没有影响。

换句话说:

  • r 一个interface{}

  • 指的是一个指针

  • 指向 astring或 a int

您的代码修改本地值r以引用指向 astring或a 的新指针int,忽略并丢弃传入的原始指针。

如果要修改指针的目标,则需要访问它。在您的接口类型上使用类型转换(例如if rstringptr, ok := r.(*string); ok { ... }或类型开关)以获取其中引用的适当类型的值。这甚至可以让您简化 API,因为您不需要在单独的参数中提供类型。例如:

import "fmt"


func get(iface interface{}) {

  switch concrete := iface.(type) {

  case *string:

    *concrete = "Nobody"

  case *int:

    *concrete = 10

  }

}


func main() {

    var b string

    get(&b)

    fmt.Println(b)

    

    var i int

    get(&i)

    fmt.Println(i)

}

https://play.golang.org/p/JyYRjH9Dchj


Nobody

10


查看完整回答
反对 回复 2022-07-04
  • 2 回答
  • 0 关注
  • 83 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信