Library for printing a struct as a compiler recognized version

116 views
Skip to first unread message

John

unread,
Aug 15, 2022, 10:26:57 AM8/15/22
to golang-nuts
I know we have plenty of pretty printing out there, but i'm looking for a package that can print the Go representation of a Struct out to screen.

So given:

var x := &myStruct{
  A: "hello"
}

someLib.Print(x)

I get:

&myStruct{
  A: "hello"
}

I'm sure someone has used reflection to do this and figured out how they want to deal with recursive pointers, so don't want to go recreate the wheel here.

Thanks.


Axel Wagner

unread,
Aug 15, 2022, 10:34:08 AM8/15/22
to John, golang-nuts
Does fmt.Printf("%#v", v) do what you want?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f4fa3f7b-318e-407b-96ef-16102db1e037n%40googlegroups.com.

John

unread,
Aug 15, 2022, 10:41:52 AM8/15/22
to golang-nuts
Hey axel,

Thanks for the reply, but unfortunately not. Because that is going to simply print pointer values out.  I want it to unwind all of that (and handle the difficulty of recursive references).  I want to be able to take what is printed and simply paste it into a file assigned to a variable, add the needed imports and have it compile.

Axel Wagner

unread,
Aug 15, 2022, 10:53:16 AM8/15/22
to John, golang-nuts
I don't believe this is possible, in general. For example, consider

type S struct {
    A *int
    B *int
}
var x S
x.A = new(int)
x.B = x.A

There is no single expression for the value of x. Or

type P *P
x := new(P)
*x = x

Then you have values which represent more than just their plain memory resources. For example, an *os.File - restoring that would not give you the same thing.

There's lots of design space here and I don't think you can solve it in full generality. So, at the very least, you have to be very deliberate about what you want and what you are willing to give up.

But. Maybe someone else has suggestions for a library doing an approximation of this you'd like better.


John

unread,
Aug 15, 2022, 11:07:54 AM8/15/22
to golang-nuts
Hey axel,

I recognize the problem space you are discussing. There are a couple strategies I could implement to try and solve the problems.  And I'm not 100% sure you can solve all of them.  But I certainly don't want to jump down the rabbit hole of reflection myself if I don't have to.  So I'm looking for a package that has attempted to do this.  I'd certainly take something that can't handle every case.

So far my googlefoo hasn't found the key words that differentiate this from pretty printing, or this type of package doesn't exist.

Thanks for your response axel.

Ian Davis

unread,
Aug 15, 2022, 11:12:44 AM8/15/22
to golan...@googlegroups.com

Sean Liao

unread,
Aug 15, 2022, 1:09:11 PM8/15/22
to golang-nuts

Dan Kortschak

unread,
Aug 15, 2022, 6:59:05 PM8/15/22
to golan...@googlegroups.com
github.com/kortschak/utter will do this for most values (there are
cases that are not possible due to requiring programmatic construction
— pointers to strings, ints etc, and filled channels being examples).

Dan

John

unread,
Aug 16, 2022, 12:23:33 AM8/16/22
to golang-nuts
Thank you everyone who responded.  Gave utter a look and its pretty decent.  I found litter a bit more developed around the circular reference area.  But both were great suggestions and just what I was looking for.

Again, thank you for helping me find these!

Dan Kortschak

unread,
Aug 16, 2022, 4:37:57 AM8/16/22
to golan...@googlegroups.com
On Mon, 2022-08-15 at 21:23 -0700, John wrote:
> Thank you everyone who responded.  Gave utter a look and its pretty
> decent.  I found litter a bit more developed around the circular
> reference area.  But both were great suggestions and just what I was
> looking for.


I would be careful with litter, it does not properly handle unexported
types or types in interface contexts.

https://go.dev/play/p/QM6zLUz0sx-
https://go.dev/play/p/hnazQoef1qP

I'd also be interested to know what you think utter is lacking in
handling circular references.

Dan

Reply all
Reply to author
Forward
0 new messages