返回介绍

选择器

发布于 2024-10-12 12:51:51 字数 1759 浏览 0 评论 0 收藏 0

对于一个 x 不是包名的主要表达式,选择器表达式:

x.f

表示 x 的字段或方法 f(有时为 *x)。标识符 f 叫做(字段/方法)选择器。它不能是空标识符。选择器表达式的类型就是 f 的类型。如果 x 是包名。请参考修饰标识符。

选择器 f 可以表示类型 T 的方法或字段 f。也可以表示类型 T 的嵌入方法或字段 f。访问 f 所需穿过的嵌套层数叫做它在类型 T 中的深度。声明在 T 中的字段或方法的深度为 0。声明在 T 的嵌入字段 A 中的方法或字段的深度等于 f 在 A 中的深度加一。

选择器遵循以下原则:

  • 对于非指针/接口类型 T/*T 的值 x,x.f 表示第一层的方法/字段。如果在第一层没有对应的 f,选择器表达式就是非法的。

  • 对于接口类型 I 的值 x, x.f 表示动态值 x 的方法名 f。如果接口 I 的方法集中没有 f 方法,选择器就是非法的。

  • 作为例外,如果 x 是一个指针类型并且 (*x).f 是合法的选择器表达式(只能表示字段,不能表示方法)。那么(*x).f 可以简写成 x.f。

  • 在其他情况下,x.f 都是非法的。

  • 如果 x 是指针类型,并且值为 nil,其中 f 为结构体字段。赋值或取值 x.f 会引起运行时恐慌。

  • 如果 x 是接口类型,并且值为 nil。调用 x.f 会引起运行时恐慌。

例如给定声明:

type T0 struct {
	x int
}

func (*T0) M0()

type T1 struct {
	y int
}

func (T1) M1()

type T2 struct {
	z int
	T1
	*T0
}

func (*T2) M2()

type Q *T2

var t T2     // with t.T0 != nil
var p *T2    // with p != nil and (*p).T0 != nil
var q Q = p

结果:

t.z          // t.z
t.y          // t.T1.y
t.x          // (*t.T0).x

p.z          // (*p).z
p.y          // (*p).T1.y
p.x          // (*(*p).T0).x

q.x          // (*(*q).T0).x        (*q).x is a valid field selector

p.M0()       // ((*p).T0).M0()      M0 expects *T0 receiver
p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
p.M2()       // p.M2()              M2 expects *T2 receiver
t.M2()       // (&t).M2()           M2 expects *T2 receiver, see section on Calls

但是下面这种方式是不合法的:

q.M0()       // (*q).M0 is valid but not a field selector

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文