Go 在结构体中定义下划线(_)字段原来还有这个特殊用途?

作者:陈明勇

个人网站:https://chenmingyong.cn

文章持续更新,如果本文能让您有所收获,欢迎点赞收藏加关注本号。 微信阅读可搜《程序员陈明勇》。 这篇文章已被收录于 GitHub https://github.com/chenmingyong0423/blog,欢迎大 家Star 催更并持续关注

前言

Go 语言中,我们经常会看到下划线(_)的使用,例如将 _ 作为占位符,用于忽略不需要的变量,或者导入但不使用的包(即 Import for side-effects),以及忽略类型转换中的变量等等。然而,大多数人可能没有见过在结构体中使用下划线(_)的情况,例如定义一个名为 _ 的结构体字段。那么,定义这样一个字段的用途是什么呢?本文将为你揭示这个疑惑。

准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。

程序员陈明勇.jpeg

有无下划线(_)字段的结构体代码示例对比

首先,我们来看不包含下划线(_)字段的结构体代码示例。

model 包里定义一个 User 结构体,包含 NameAge 两个字段。

type User struct {
    Name string
    Age  int
}

使用 位置初始化具名字段初始化 两种方式声明结构体变量。

user := model.User{"陈明勇", 18}
user = model.User{Name: "陈明勇", Age: 18}

在上述代码中,无论是定义结构体,还是声明结构体,都没有任何问题。

我们再来看下包含下划线(_)字段的结构体代码例子:

model 包里定义一个 User 结构体,包含 NameAge 以及 _ 三个字段。

type User struct {
    Name string
    Age  int
    _    struct{}
}

使用 位置初始化具名字段初始化 两种方式声明结构体变量。

// 编译错误 too few values in struct literal of type model.User
user := model.User{"陈明勇", 18}
// 编译错误 implicit assignment to unexported field _ in struct literal of type model.User
user = model.User{"陈明勇", 18, struct{}{}}
// 正常
user = model.User{}
user = model.User{Name: "陈明勇", Age: 18}

在上述例子中,如果通过 user := model.User{"陈明勇", 18}model.User{"陈明勇", 18, struct{}{}} 这两种 位置初始化 的方式声明结构体变量,程序将会编译错误,而通过 零值初始化具名字段初始化 的方式去声明结构体变量则没有问题。

通过对比有无下划线(_)字段的结构体代码示例,我们可以总结出在结构体中定义下划线(_)字段的用途:在结构体中定义一个名为 _ 的字段,可以强制要求该结构体在初始化时必须使用具名字段初始化(声明零值结构体变量的场景除外)。

原理浅析

当我们使用 位置初始化 的方式声明结构体时,需要按照结构体字段的顺序依次提供所有字段的值。

如果在结构体中定义了一个名为 _ 的字段,那么使用 位置初始化 的方式时,如果没有提供 _ 字段的值,编译器会提示 too few values in struct literal of type XXX,这是因为没有提供所有的结构体字段值。

即使按照结构体字段的顺序提供了所有字段的值,编译器也会报错,提示 implicit assignment to unexported field _ in struct literal of type XXX。这是因为 _ 字段的首字母没有大写,被认为是未导出的字段,我们不能隐式赋值给未导出的字段,因此不能通过位置初始化进行赋值。

综上所述,由于无法通过 位置初始化 的方式去声明这个结构体的变量,我们只能通过 零值初始化具名字段初始化 的方式去声明结构体变量。

小结

通过本文的探讨,我们了解了在 Go 语言中结构体字段命名使用下划线(_)的特殊用途。

具体来说,定义一个名为 _ 的字段可以有效地强制开发者在初始化结构体时使用具名字段初始化,而不是位置初始化。这样做的好处包括:

  • 代码可读性:具名字段初始化使得代码更具可读性和可维护性,因为每个字段的值都显式地与字段名关联。
  • 避免错误:位置初始化需要严格遵循字段顺序,容易引入错误。具名字段初始化则避免了这一问题。
  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员陈_明勇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值