fmt.Printf函数的标志位是什么,可以递归地跟踪指针?

huangapple go评论73阅读模式
英文:

What flag to fmt.Printf to follow pointers recursively?

问题

我在处理失败的测试用例时遇到了打印结构体的问题。它是一个指向结构体指针切片的指针,即*[]*X。问题是我需要知道切片中X结构体的内容,但我无法打印整个链表。它只打印它们的地址,因为它是一个指针。我需要它跟随指针。

然而,这是无用的,因为我想要测试的函数会修改它们的内容,而修改测试代码以不使用指针意味着我不使用指针测试代码(所以这样行不通)。

此外,仅仅通过循环遍历切片也行不通,因为真正的函数使用反射并可能处理多层指针。

简化示例:

package main

import "fmt"

func main() {
    type X struct {
        desc string
    }

    type test struct {
        in   *[]*X
        want *[]*X
    }

    test1 := test{
        in: &[]*X{
            &X{desc: "first"},
            &X{desc: "second"},
            &X{desc: "third"},
        },
    }

    fmt.Printf("%#v", test1)
}

示例输出:

main.test{in:(*[]*main.X)(0x10436180), want:(*[]*main.X)(nil)}

(代码位于http://play.golang.org/p/q8Its5l_lL)

英文:

I'm having trouble printing a struct when failing test cases. It's a pointer to a slice of pointers to structs, or *[]*X. The problem is that I need to know the contents of the X-structs inside the slice, but I cannot get it to print the whole chain. It only prints their addresses, since it's a pointer. I need it to follow the pointers.

This is however useless since the function I want to test modifies their contents, and modifying the test code to not use pointers just means I'm not testing the code with pointers (so that wouldn't work).

Also, just looping through the slice won't work, since the real function uses reflect and might handle more than one layer of pointers.

Simplified example:

package main

import "fmt"

func main() {
	type X struct {
		desc string
	}

	type test struct {
		in   *[]*X
		want *[]*X
	}

	test1 := test{
		in: &[]*X{
			&X{desc: "first"},
			&X{desc: "second"},
			&X{desc: "third"},
		},
	}

	fmt.Printf("%#v", test1)
}

example output:

main.test{in:(*[]*main.X)(0x10436180), want:(*[]*main.X)(nil)}

(code is at http://play.golang.org/p/q8Its5l_lL )

答案1

得分: 14

我不认为fmt.Printf具有你所寻找的功能。

你可以使用https://github.com/davecgh/go-spew库。

spew.Dump(test1)

英文:

I don't think fmt.Printf has the functionality you are looking for.

You can use the https://github.com/davecgh/go-spew library.

spew.Dump(test1)

答案2

得分: 0

你可以使用valast库作为替代方案,使用valast.String()方法。

例如,输出如下:

test{in: &[]*X{
    {desc: "first"},
    {desc: "second"},
    {desc: "third"},
}}

对于spew,使用spew.Sdump()方法,输出如下:

(main.test) {
 in: (*[]*main.X)(0xc000098090)((len=3 cap=3) {
  (*main.X)(0xc000088300)({
   desc: (string) (len=5) "first"
  }),
  (*main.X)(0xc000088310)({
   desc: (string) (len=6) "second"
  }),
  (*main.X)(0xc000088320)({
   desc: (string) (len=5) "third"
  })
 }),
 want: (*[]*main.X)(<nil>)
}
英文:

You can use the valast (valast.String()) library alternatively.
For the example the out is:

test{in: &amp;[]*X{
    {desc: &quot;first&quot;},
    {desc: &quot;second&quot;},
    {desc: &quot;third&quot;},
}}

For spew (spew.Sdump()) it looks like:

(main.test) {
 in: (*[]*main.X)(0xc000098090)((len=3 cap=3) {
  (*main.X)(0xc000088300)({
   desc: (string) (len=5) &quot;first&quot;
  }),
  (*main.X)(0xc000088310)({
   desc: (string) (len=6) &quot;second&quot;
  }),
  (*main.X)(0xc000088320)({
   desc: (string) (len=5) &quot;third&quot;
  })
 }),
 want: (*[]*main.X)(&lt;nil&gt;)
}     

huangapple
  • 本文由 发表于 2015年2月14日 04:21:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/28508128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定