【问题标题】:Print type of a structure without creating its instance打印结构的类型而不创建其实例
【发布时间】:2014-09-01 21:21:02
【问题描述】:

在 Go 中,我可以通过 fmt.Printf("%T",Struct{}) 打印一种结构类型,但这会创建一个新结构并因此占用内存。所以我可能只打印fmt.Printf("main.Struct"),但是假设有人重构了Struct 的名称,那么打印语句没有得到更新并且代码中断。

如何在不创建实例的情况下打印结构类型?

【问题讨论】:

  • 你真正想要达到什么目的?即在不创建实例的情况下打印类型对您有什么帮助?
  • 这是用于错误报告errors.New(fmt.Sprintf("expected structure of type %T, but provided a structure of type %T", Struct{}, object)),因此不会破坏任何脚本,但提供的信息会产生误导。我将问题保持一般性,因为在某些情况下重构也可能破坏脚本。

标签: go


【解决方案1】:

其中一种解决方案是使用包reflect

fmt.Printf("%v", reflect.TypeOf((*Struct)(nil)).Elem())

它不会创建结构的任何实例。它将打印main.Struct

【讨论】:

  • 有一个不使用反射的更简单的解决方案,我会接受那个。
  • 您不会进行反思,因为您正在处理一种您不知道的类型。您可以使用类型开关检查它们,但最终反射是要走的路。
【解决方案2】:

它将总是使用反射来获取类型的名称,句号。

内部fmt.Printf("%T", x) 使用reflect.TypeOf(x)(来源:http://golang.org/src/pkg/fmt/print.go#L721

使用可以使用fmt.Sprintf,但它仍然使用反射+解析格式字符串的额外开销。

name := fmt.Sprintf("%T", (*S)(nil))[1:] //lose the *
// or
name := reflect.TypeOf((*S)(nil)).String()[1:]

【讨论】:

  • 为什么不使用Elem()
  • @nemo Elem() 只能与 reflect 包一起使用。但是由于%T内部使用了reflect包,所以可能没有必要避免直接使用。
猜你喜欢
  • 2015-05-08
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-21
  • 2019-04-02
  • 1970-01-01
相关资源
最近更新 更多