diff --git a/doc/go_spec.html b/doc/go_spec.html index abe26fc4192..6a21c6cabf4 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1750,7 +1750,7 @@ and a type. Operands denote the elementary values in an expression.
-Operand = Literal | QualifiedIdent | "(" Expression ")" . +Operand = Literal | QualifiedIdent | MethodExpr | "(" Expression ")" . Literal = BasicLit | CompositeLit | FunctionLit . BasicLit = int_lit | float_lit | char_lit | StringLit .@@ -2710,122 +2710,6 @@ to by the operand. *pf(x) -
-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. -Consider the type T with method M: -
- --type T struct { - a int; -} -func (tp *T) M(a int) int; -var t *T; -- -
-To construct the value of method M, one writes -
- --t.M -- -
-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 -
- --func (t *T, a int) int -- -
-and may be invoked only as a function, not as a method: -
- --var f func (t *T, a int) int; -f = t.M; -x := f(t, 7); -- -
-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 -
- --t.M(args) -- -
-is equivalent to the function call -
- --(t.M)(t, args) -- -
- -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 -
- --var t1 *T1; -var t2 *T2; -var i I = t1; -m := i.M; -m(t2, 7); -- -
-will invoke t2.M() even though m was constructed with an expression involving -t1. Effectively, the value of m is a function literal -
- --func (recv I, a int) { - recv.M(a); -} -- -
-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?) - -
-@@ -2915,10 +2799,128 @@ zero value for its type (§The zero value).
-TODO: Probably in a separate section, communication semantices +TODO: Probably in a separate section, communication semantics need to be presented regarding send, receive, select, and goroutines.
+
+If M
is in the method set of type T
,
+T.M
is a function that is callable as a regular function
+with the same arguments as M
prefixed by an additional
+argument that is the receiver of the method.
+
+MethodExpr = ReceiverType "." MethodName . +ReceiverType = TypeName | "(" "*" TypeName ")" . +MethodName = identifier . ++ +
+Consider a struct type T
with two methods,
+Mv
, whose receiver is of type T
, and
+Mp
, whose receiver is of type *T
.
+
+type T struct { + a int; +} +func (tv T) Mv(a int) int { return 0 } // value receiver +func (tp *T) Mp(f float) float { return 1 } // pointer receiver +var t T; ++ +
+The expression +
+ ++T.Mv ++ +
+yields a function equivalent to Mv
but
+with an explicit receiver as its first argument; it has signature
+
+func (tv T, a int) int ++ +
+That function may be called normally with an explicit receiver, so +these three invocations are equivalent: +
+ ++t.Mv(7) +T.Mv(t, 7) +f := T.Mv; f(t, 7) ++ +
+Similarly, the expression +
+ ++(*T).Mp ++ +
+yields a function value representing Mp
with signature
+
+func (tp *T, f float) float ++ +
+For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +
+ ++(*T).Mv ++ +
+yields a function value representing Mv
with signature
+
+func (tv *T, f int) int ++ +
+Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +
+ ++The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +
+ +
+Function values derived from methods are called with function call syntax;
+the receiver is provided as the first argument to the call.
+That is, given f := T.Mv
, f
is invoked
+as f(t, 7)
not t.f(7)
.
+To construct a function that binds the receiver, use a
+closure.
+
+It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +
+
@@ -4309,8 +4311,8 @@ mentions B
, or mentions a function that
mentions B
, recursively.
If two items are not interdependent, they will be initialized
in the order they appear in the source.
-Since the dependency analysis is done per package, it can be
-defeated if A
's initializer calls a function defined
+Since the dependency analysis is done per package, it can produce
+unspecified results if A
's initializer calls a function defined
in another package that refers to B
.