Selectors
这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。
For a primary expression x
that is not a package name, the selector expression
x.f
denotes the field or method f
of the value x
(or sometimes *x
; see below). The identifier f
is called the (field or method) selector; it must not be the blank identifier. The type of the selector expression is the type of f
. If x
is a package name, see the section on qualified identifiers.
A selector f
may denote a field or method f
of a type T
, or it may refer to a field or method f
of a nested embedded field of T
. The number of embedded fields traversed to reach f
is called its depth in T
. The depth of a field or method f
declared in T
is zero. The depth of a field or method f
declared in an embedded field A
in T
is the depth of f
in A
plus one.
The following rules apply to selectors:
- For a value
x
of typeT
or*T
whereT
is not a pointer or interface type,x.f
denotes the field or method at the shallowest depth inT
where there is such anf
. If there is not exactly onef
with shallowest depth, the selector expression is illegal. - For a value
x
of typeI
whereI
is an interface type,x.f
denotes the actual method with namef
of the dynamic value ofx
. If there is no method with namef
in the method set ofI
, the selector expression is illegal. - As an exception, if the type of
x
is a defined pointer type and(*x).f
is a valid selector expression denoting a field (but not a method),x.f
is shorthand for(*x).f
. - In all other cases,
x.f
is illegal. - If
x
is of pointer type and has the valuenil
andx.f
denotes a struct field, assigning to or evaluatingx.f
causes a run-time panic. - If
x
is of interface type and has the valuenil
, calling or evaluating the methodx.f
causes a run-time panic.
For example, given the declarations:
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
one may write:
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
but the following is invalid:
q.M0() // (*q).M0 is valid but not a field selector
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。