Golang 语言怎么打印结构体指针类型字段的值?

开发 后端
在 Golang 语言开发中,我们经常会使用结构体类型,如果我们使用的结构体类型的变量包含指针类型的字段,我们在记录日志的时候,指针类型的字段的值是指针地址,将会给我们 debug 代码造成不便。

01介绍

在 Golang 语言开发中,我们经常会使用结构体类型,如果我们使用的结构体类型的变量包含指针类型的字段,我们在记录日志的时候,指针类型的字段的值是指针地址,将会给我们 debug 代码造成不便。

实际上,Golang 为我们提供了一个接口类型 Stringer ,它是一个支持以字符串形式描述自己的类型,它只提供了一个方法,应该是 Golang 中最简单和最常用的接口之一,它由 fmt 包定义。

  1. type Stringer interface { 
  2.     String() string 

fmt 包的打印函数会检查你的类型是否实现该接口,以便知道怎么打印你的变量。所以,我们在记录日志的时候,如果需要记录的变量是具有指针类型字段的结构体,我们不妨也为该结构体类型定义 String 方法,用来实现可以记录指针字段的实际值的目的。

本文我们介绍怎么通过实现 Stringer 接口,让我们的代码更优雅。

02打印指针类型的值

读者朋友们在 Golang 程序开发中,一定也会使用到包含指针类型字段的结构体,你是否在记录日志的时候,发现记录的值是指针地址,给你 debug 代码造成不便呢?

  1. func main() { 
  2.  name := "frank" 
  3.  user := User
  4.   Id:   1, 
  5.   Name: &name
  6.  } 
  7.  fmt.Println(user
  8.  
  9. type User struct { 
  10.  Id   int 
  11.  Name *string 

输出结果:

  1. {1 0xc000096210} 

阅读上面这段代码,我们构造了一个包含指针类型字段的结构体,然后打印该结构体类型的变量,输出结果中指针类型的字段 Name 的值是指针地址,而不是我们想要的字段值 frank。

试想一下,如果我们记录的日志中,变量的值是指针地址,将会对我们 debug 代码造成不变,所以我们需要使用 Golang 提供的接口 Stringer 解决该问题。

  1. func (u User) String() string { 
  2.  return fmt.Sprintf("{Id: %v, Name: %v}", u.Id, *u.Name

输出结果:

  1. {Id: 1, Name: frank} 

阅读上面这段代码,我们给类型 User 定义了 String 方法,通过实现 Golang 的 Stringer 接口,来实现打印指针类型变量的实际值的目的。

03避“坑”

读者朋友们阅读完以上内容,应该已经学会了怎么使用接口 Stringer 实现打印指针类型变量的值。不过,我还是想列举一个异常情况,帮助 Golang 新手读者朋友避“坑”。如果你已经是 Golang 老手,本节内容可以跳过。

  1. func (u *User) String() string { 
  2.  return fmt.Sprintf("{Id: %v, Name: %v}", u.Id, *u.Name

阅读上面这段代码,我们将类型方法的接收者改为指针类型,我相信大多数读者朋友们会使用指针类型的接收者。此时,读者朋友会发现输出结果没有使用我们定义的 String 方法,而是输出的指针类型字段的指针地址。

想要解决这个问题也很简单,我们只需要在定义结构体类型变量的时候,使用指针类型,这样 fmt 包的打印函数就可以自动执行我们定义的 String 方法了。

  1. func main() { 
  2.  name := "frank" 
  3.  user := &User
  4.   Id:   1, 
  5.   Name: &name
  6.  } 
  7.  fmt.Println(user

04总结

本文我们介绍了怎么打印包含指针类型变量的结构体类型变量的值,在我们需要记录日志的时候,不用再因为记录的是指针地址,从而给我们 debug 代码造成不便。

参考资料:

https://go.dev/doc/effective_go#pointers_vs_values

 

https://go.dev/tour/methods/17

 

责任编辑:武晓燕 来源: Golang语言开发栈
相关推荐

2021-06-01 23:18:00

Golang语言Method

2023-08-28 17:16:51

Golangio 包

2022-01-04 23:13:57

语言PanicGolang

2021-05-11 11:31:52

C语言类型指针

2014-04-01 10:11:33

C语言指针

2021-07-12 05:05:59

Golang语言字段

2009-08-31 15:02:22

C#解析结构体指针

2023-06-09 08:16:09

GolangStruct Tag

2023-07-29 15:03:29

2022-09-18 23:09:13

Go语言标准库

2009-08-14 11:05:28

C#语言的结构体

2021-04-20 09:00:48

Go 语言结构体type

2021-06-09 23:36:46

Golang语言版本

2009-08-13 15:41:50

C#结构体指针

2022-01-12 08:30:55

结构体指针STM32

2014-02-10 15:05:37

C语言封装

2023-07-11 08:22:09

2021-09-13 05:02:49

GogRPC语言

2021-06-07 23:19:44

Golang语言 Defer

2009-08-31 14:34:46

C#值类型C#结构类型
点赞
收藏

51CTO技术栈公众号