Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

golang how to print struct value with pointer

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
like image 553
user7827949 Avatar asked Apr 06 '17 15:04

user7827949


People also ask

How do I print a struct with fields in go?

In Golang, we can print the structure's fields with their names using the following: Marshal() function of encoding/json package. Printf() function of fmt package.

Is struct a pointer in Golang?

Structs and pointers in Go Programming In Golang, a struct is a user-defined type of language that allows elements of different types to be combined into a single type. The & operator, also known as the address operator, can be used to use a pointer to a struct.

How do I find the variable address in Golang?

In Go language, we get the memory address of a variable by adding the & symbol in front of the variable, this operation is also called address fetching.


2 Answers

Use fmt and reflect.

package main

import (
    "fmt"
    "reflect"
)

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

func main() {
    a := &A{
        a: 1,
        B: &B{
            b: 2,
        },
    }
    fmt.Printf("%s\n", GetGoString(a)) // output: &A{a: 1, B: &B{b: 2}}
}

func GetGoString(v interface{}) string {
    return getGoString(reflect.ValueOf(v))
}

func getGoString(v reflect.Value) string {
    switch v.Kind() {
    case reflect.Invalid:
        return "nil"
    case reflect.Struct:
        t := v.Type()
        out := getTypeString(t) + "{"
        for i := 0; i < v.NumField(); i++ {
            if i > 0 {
                out += ", "
            }
            fieldValue := v.Field(i)
            field := t.Field(i)
            out += fmt.Sprintf("%s: %s", field.Name, getGoString(fieldValue))
        }
        out += "}"
        return out
    case reflect.Interface, reflect.Ptr:
        if v.IsZero() {
            return fmt.Sprintf("(%s)(nil)", getTypeString(v.Type()))
        }
        return "&" + getGoString(v.Elem())
    case reflect.Slice:
        out := getTypeString(v.Type())
        if v.IsZero() {
            out += "(nil)"
        } else {
            out += "{"
            for i := 0; i < v.Len(); i++ {
                if i > 0 {
                    out += ", "
                }
                out += getGoString(v.Index(i))
            }
            out += "}"
        }
        return out
    default:
        return fmt.Sprintf("%#v", v)
    }
}

func getTypeString(t reflect.Type) string {
    if t.PkgPath() == "main" {
        return t.Name()
    }
    return t.String()
}
like image 142
Jaber Avatar answered Oct 13 '22 20:10

Jaber


Another simple solution is to print the struct using marshaling. This works only for exported (public) variables by capitalizing the first char inside the struct.

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))
}

Output :-

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

If you are printing the struct multiple times then implement Stringer interface as follows :-

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)
}

Output -

YAML Print - 
aa: 1
b:
  bb: 2
like image 40
dganesh2002 Avatar answered Oct 13 '22 19:10

dganesh2002