From afee1c5f0c1907bc575e1f87fc18889f0979cab0 Mon Sep 17 00:00:00 2001
From: Rob Pike
-TODO: Need to talk about unary "*", clean up section below.
+The unary prefix address-of operator
TODO: This text needs to be cleaned up and go elsewhere, there are no address
operators involved.
+
-Methods are a form of function, and a method ``value'' has a function type.
+Methods are a form of function and a method ``value'' has a function type.
Consider the type T with method M:
+
To construct the value of method M, one writes
+
using the variable t (not the type T).
TODO: It makes perfect sense to be able to say T.M (in fact, it makes more
sense then t.M, since only the type T is needed to find the method M, i.e.,
its address). TBD.
+
The expression t.M is a function value with type
+
and may be invoked only as a function, not as a method:
+
Note that one does not write t.f(7); taking the value of a method demotes
it to a function.
+
In general, given type T with method M and variable t of type T,
the method invocation
+
is equivalent to the function call
+
TODO: should probably describe the effect of (t.m) under §Expressions if t.m
denotes a method: Effect is as described above, converts into function.
+
If T is an interface type, the expression t.M does not determine which
underlying type's M is called until the point of the call itself. Thus given
T1 and T2, both implementing interface I with method M, the sequence
+
will invoke t2.M() even though m was constructed with an expression involving
t1. Effectively, the value of m is a function literal
+
that is automatically created.
+
TODO: Document implementation restriction: It is illegal to take the address
of a result parameter (e.g.: func f() (x int, p *int) { return 2, &x }).
(TBD: is it an implementation restriction or fact?)
+Address operators
-
-
&
generates the address of its operand, which must be a variable,
+pointer indirection, field selector, or array or slice indexing operation. It is illegal to take the address of a function
+result variable.
+Given an operand of pointer type, the unary prefix pointer indirection operator *
retrieves the value pointed
+to by the operand.
+
+&x
+&a[f(2)]
+*p
+*pf(x)
+
+
type T struct {
@@ -2684,25 +2696,33 @@ func (tp *T) M(a int) int;
var t *T;
+
t.M
+
func (t *T, a int) int
+
var f func (t *T, a int) int;
@@ -2710,30 +2730,39 @@ f = t.M;
x := f(t, 7);
+
t.M(args)
+
(t.M)(t, args)
+
var t1 *T1;
@@ -2743,8 +2772,10 @@ m := i.M;
m(t2, 7);
+
func (recv I, a int) {
@@ -2752,13 +2783,16 @@ func (recv I, a int) {
}
+Communication operators
@@ -3131,11 +3165,13 @@ if x := f(); x < y {
An expression or type specifier is compared to the "cases"
inside the "switch" to determine which branch
to execute.
+
SwitchStat = ExprSwitchStat | TypeSwitchStat .+
There are two forms: expression switches and type switches. In an expression switch, the cases contain expressions that are compared against the value of the switch expression. @@ -3690,7 +3726,6 @@ for i := 0; i <= 3; i++ {