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

Go:指向 interface{} 的指针丢失了底层类型

Go:指向 interface{} 的指针丢失了底层类型

Go
慕慕森 2021-08-30 16:31:28
我正在使用 Go 中的一些“通用”函数,这些函数在interface{}通道上运行和发送东西等等。瘦下来,假设我有这样的东西:type MyType struct {    // Fields}func (m *MyType) MarshalJSON() ([]byte, error) {    // MarshalJSON    log.Print("custom JSON marshal")    return []byte("hello"), nil}func GenericFunc(v interface{}) {    // Do things...    log.Print(reflect.TypeOf(v))    log.Print(reflect.TypeOf(&v))    b, _ = json.Marshal(&v)    fmt.Println(string(b))}func main() {    m := MyType{}    GenericFunc(m)}这输出:2014/11/16 12:41:44 MyType 2014/11/16 12:41:44 *interface {}其次是默认json.Marshal输出,而不是自定义输出。据我所知,这是因为调用Marshal看到的是指向接口的指针而不是指向 MyType 的指针类型的值。为什么我在服用时会丢失类型信息&v?我希望输出的第二行是*MyType而不是*interface {}.有什么方法可以让我在不显式转换的情况下调用自定义 JSON Marshaller?
查看完整描述

2 回答

?
梦里花落0921

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

只需将指针传递给您的结构,而不是将其值传递给函数。指针仍然存在,interface{}但是指向接口的指针是没有意义的。


查看完整回答
反对 回复 2021-08-30
?
萧十郎

TA贡献1815条经验 获得超13个赞

听起来您想通过 a 发送非指针值chan interface{}并让自定义MarshalJSON方法按预期工作。在这种情况下,不要在指针类型上定义方法。


package main


import (

    "encoding/json"

    "fmt"

    "log"

    "time"

)


func printer(in chan interface{}) {

    for val := range in {

        buf, err := json.Marshal(val)

        if err != nil {

            log.Println(err.Error())

        }

        log.Println(string(buf))

    }

}


type MyType struct {

    name string

}


func (m MyType) MarshalJSON() ([]byte, error) {

    return []byte(fmt.Sprintf(`"%s"`, m.name)), nil

}


func main() {

    ch := make(chan interface{})


    go printer(ch)

    ch <- "string value"

    ch <- 25

    ch <- MyType{

        name: "foo",

    }


    time.Sleep(time.Second)

}

唯一真正的区别是方法接收器。func (m MyType) MarshalJSON ([]byte, error)代替func (m *MyType) MarshalJSON ([]byte, error)


查看完整回答
反对 回复 2021-08-30
  • 2 回答
  • 0 关注
  • 256 浏览
慕课专栏
更多

添加回答

举报

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