Первичные выражения (primary expressions) являются операндами для унарных и двоичных выражений.
PrimaryExpr =
Operand |
Conversion |
MethodExpr |
PrimaryExpr Selector |
PrimaryExpr Index |
PrimaryExpr Slice |
PrimaryExpr TypeAssertion |
PrimaryExpr Arguments .
Selector = "." identifier .
Index = "[" Expression "]" .
Slice = "[" [ Expression ] ":" [ Expression ] "]" |
"[" [ Expression ] ":" Expression ":" Expression "]" .
TypeAssertion = "." "(" Type ")" .
Arguments = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
Примеры первичных выражений:
x
2
(s + ".txt")
f(3.1415, true)
Point{1, 2}
m["foo"]
s[i : j + 1]
obj.color
f.p[i].x()
Селекторы (Selectors)
Для первичного выражения (primary expression) x, которое не является именем пакета, выражение селектора (selector expression)
x.f
обозначает поле или метод f значения x (или иногда *x). Идентификатор f называется селектором (поля или метода); это не должен быть пустой идентификатор. Тип выражения селектора (selector expression) - это тип f.
Селектор f может обозначать поле или метод f типа T, или он может ссылаться на поле или метод f вложенного встроенного (embedded) поля T. Число встроенных (embedded) полей, пройденных для достижения f, называется его глубиной (depth) в T. Глубина поля или метода f, объявленного в T, равна нулю. Глубина поля или метода f, объявленного во встроенном поле A в T, равна глубине f в A плюс один.
Следующие правила применяются к селекторам:
- Для значения x типа T или *T, где T не является указателем или интерфейсным типом, x.f обозначает поле или метод на самой малой глубине в T, где есть такое f. Если нет точно одного f с наименьшей глубиной, выражение селектора (selector expression) недопустимо.
- Для значения x типа I, где I является типом интерфейса, x.f обозначает фактический метод с именем f динамического значения x. Если в наборе методов I нет метода с именем f, выражение селектора (selector expression) недопустимо.
- В качестве исключения, если тип x является определенным типом указателя и (*x).f является допустимым выражением селектора, обозначающим поле (но не метод), x.f является сокращением для (*x).f.
- Во всех остальных случаях x.f является недопустимым.
- Если x имеет тип указателя и имеет значение nil, а x.f обозначает поле структуры, назначение или оценка (evaluating) x.f вызывает панику во время выполнения (run-time panic).
- Если 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 // при условии что t.T0 != nil
var p *T2 // при условии что p != nil и (*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 это допустимый селектор поля
p.M0() // ((*p).T0).M0() M0 ожидает *T0 получатель
p.M1() // ((*p).T1).M1() M1 ожидает T1 получатель
p.M2() // p.M2() M2 ожидает *T2 получатель
t.M2() // (&t).M2() M2 ожидает *T2 получатель
но следующее недопустимо:
q.M0() // (*q).M0 допустимо, но не селектор поля
Читайте также:
- Спецификация Go: литералы
- Спецификация Go: составные литералы (composite literals)
- Спецификация Go: выражения (expressions) - операнды, квалифицированные идентификаторы
Комментариев нет:
Отправить комментарий