微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在String方法中打印原始go struct

如何解决如何在String方法中打印原始go struct

我的结构定义如下

type WallpaperType int

// ...

type WallpaperInfo struct {
    WallpaperType WallpaperType `json:"type"`
    HelpMsg       string        `json:"help"`
    Path          string        `json:"path"`
    ImageColor    color.RGBA    `json:"imageColor"`
}

使用以下命令打印此类结构

winfo := &WallpaperInfo{...}
log.Println(winfo)
log.Printf("%+v\n",winfo)

给出这样的内容

&{Slideshow Wallpaper is a slideshow D:\Images\Wallpapers\autumn-autumn-leaves-blur-close-up-589840.jpg {219 77 66 167}}

&{WallpaperType:Slideshow HelpMsg:Wallpaper is a slideshow Path:D:\Images\Wallpapers\autumn-autumn-leaves-blur-close-up-589840.jpg ImageColor:{R:219 G:77 B:66 A:167}}

我想将其打印为JSON,所以我为结构实现了String方法,如下所示

func (w WallpaperInfo) String() string {
    bytes,err := json.Marshal(w)
    if err != nil {
        return "" // ???
        // this will call the method recursively
        // return fmt.Sprintf("%+v\n",w)
    }
    return string(bytes)
}

如果String()方法出错,

我想打印原始的&{WallpaperType:Slideshow HelpMsg:Wallpaper is a slideshow Path:D:\Images\Wallpapers\autumn-autumn-leaves-blur-close-up-589840.jpg ImageColor:{R:219 G:77 B:66 A:167}}

我尝试返回fmt.Sprintf("%+v\n",w),但它确实递归调用同一函数

有什么方法可以返回原始结构格式?因为如果json失败,我不知道以其他方式打印它的方式。

解决方法

使用WallpaperInfo作为其new type创建一个underlying type,并在将值传递给convert之前创建fmt.Sprintf()值。创建新类型会将其从所有方法中删除,包括String()方法:

func (w WallpaperInfo) String() string {
    bytes,err := json.Marshal(w)
    if err != nil {
        type wi WallpaperInfo
        return fmt.Sprintf("%+v\n",wi(w))
    }
    return string(bytes)
}

尽管您的类型永远不会返回JSON封送处理错误,但是在一般情况下,这是您可以实现所需目标的方法。

下面是一个示例,该示例故意使JSON封送失败,并且将退回到原始的结构字符串表示形式:

type fail int

func (fail) MarshalJSON() ([]byte,error) {
    return nil,errors.New("on-purpose error")
}

type MyStruct struct {
    F fail
}

func (m MyStruct) String() string {
    bytes,err := json.Marshal(m)
    if err != nil {
        log.Printf("JSON error: %v",err)
        type ms MyStruct
        return fmt.Sprintf("%+v\n",ms(m))
    }
    return string(bytes)
}

测试:

s := MyStruct{}

log.Println(s)
log.Printf("%+v\n",s)

哪个会输出(在Go Playground上尝试):

2009/11/10 23:00:00 JSON error: json: error calling MarshalJSON for type main.fail: on-purpose error
2009/11/10 23:00:00 {F:0}

2009/11/10 23:00:00 JSON error: json: error calling MarshalJSON for type main.fail: on-purpose error
2009/11/10 23:00:00 {F:0}

查看相关问题:

Call json.Unmarshal inside UnmarshalJSON function without causing stack overflow

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。