diff --git a/doc/go_spec.html b/doc/go_spec.html index abe26fc419..6a21c6cabf 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.