golang如何用指针打印struct值

时间:2017-04-06 15:48:18

标签: pointers go struct printing

package main

import "fmt"

type A struct {
    a int32
    B *B
}
type B struct {
    b int32
}

func main() {
    a := &A{
        a: 1,
        B: &B{
            b: 2,
        },
    }
    fmt.Printf("v ==== %+v \n", a)
}


//ret: v ==== &{a:1 B:0xc42000e204}
//??? how to print B's content but not pointer

3 个答案:

答案 0 :(得分:4)

基本上,你必须自己做。有两种方法可以做到这一点。要么只打印你想要的东西,要么通过添加Stringer来实现结构的func String() string接口,当你使用格式%v时会调用它。您还可以使用结构格式引用每个值。

实现Stringer接口是始终获得所需内容的最可靠方法。而且每个结构只需要执行一次,而不是在打印时使用每个格式字符串。

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

package main

import "fmt"

type A struct {
    a int32
    B *B
}

type B struct{ b int32 }

func (aa *A) String() string {
    return fmt.Sprintf("A{a:%d, B:%v}",aa.a,aa.B)
}

func (bb *B) String() string {
    return fmt.Sprintf("B{b:%d}",bb.b)
}

func main() {
    a := &A{a: 1, B: &B{b: 2}}

    // using the Stringer interface
    fmt.Printf("v ==== %v \n", a)

    // or just print it yourself however you want.
    fmt.Printf("v ==== A{a:%d, B:B{b:%d}}\n", a.a, a.B.b)

    // or just reference the values in the struct that are structs themselves
    // but this can get really deep
    fmt.Printf("v ==== A{a:%d, B:%v}", a.a, a.B)
}

答案 1 :(得分:1)

当您进入更大的结构时,编写一堆自定义String函数变得很痛苦。 Goconvey当前使用以下项目在任何大小的结构上显示差异和预期/实际输出:https://github.com/luci/go-render/blob/master/render/render.go#L51。它包括显示指针值。

如果您需要将输出可重复用作代码(例如fmt.Printf("%#v", a)但包含指针值),则可以使用上述项目的分叉版本,它将完整的嵌套指针呈现为可重复使用的代码:< / p>

package main

import (
    "fmt"
    "github.com/gdexlab/go-render/render"
)

type A struct {
    a int32
    B *B
}
type B struct {
    b int32
}

func main() {
    a := &A{
        a: 1,
        B: &B{
            b: 2,
        },
    }
    output := render.AsCode(a)
    fmt.Println(output)

}
// outputs: "&A{a:1, B:&B{b:2}}" compared to initial version of "&{a:1 B:0xc42000e204}"

去游乐场示例: https://play.golang.org/p/tcfJYb0NnVf

答案 2 :(得分:1)

另一个简单的解决方案是使用封送处理打印结构。这仅适用于通过将结构中的第一个字符大写来导出(公共)变量。

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
    "encoding/json"
)

type A struct {
    Aa int32
    B *B
}
type B struct {
    Bb int32
}
func main() {
    a := &A{
        Aa: 1,
        B: &B{
            Bb: 2,
        },
    }
    aJSON, _ := json.Marshal(a)
    fmt.Printf("JSON Print - \n%s\n", string(aJSON))


    aYAML, _ := yaml.Marshal(a)
    fmt.Printf("YAML Print - \n%s\n", string(aYAML))
}

输出:-

JSON Print - 
{"Aa":1,"B":{"Bb":2}}
YAML Print - 
aa: 1
b:
  bb: 2

如果你多次打印结构体,那么实现 Stringer 接口如下:-

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
)

type A struct {
    Aa int32
    B *B
}

func (a A) String() string {
    bytes, _ := yaml.Marshal(a)
    return string(bytes)
}

type B struct {
    Bb int32
}

func main() {
    a := &A{
        Aa: 1,
        B: &B{
            Bb: 2,
        },
    }

    fmt.Printf("YAML Print - \n%+v\n", a)
}

输出 -

YAML Print - 
aa: 1
b:
  bb: 2