diff --git a/doc/go_spec.html b/doc/go_spec.html index a32fa457c9..a5edc8646c 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -2537,6 +2537,233 @@ p.M0() // ((*p).T0).M0() +

Method expressions

+ +

+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 ")" | "(" ReceiverType ")" .
+
+ +

+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 float32) float32 { 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 five invocations are equivalent: +

+ +
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+
+ +

+Similarly, the expression +

+ +
+(*T).Mp
+
+ +

+yields a function value representing Mp with signature +

+ +
+func(tp *T, f float32) float32
+
+ +

+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, a 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 +function literal or +method value. +

+ +

+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. +

+ +

Method values

+ +

+If the expression x has static type T and +M is in the method set of type T, +x.M is called a method value. +The method value x.M is a function value that is callable +with the same arguments as a method call of x.M. +The expression x is evaluated and saved during the evaluation of the +method value; the saved copy is then used as the receiver in any calls, +which may be executed later. +

+ +

+The type T may be an interface or non-interface type. +

+ +

+As in the discussion of method expressions above, +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 float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+
+ +

+The expression +

+ +
+t.Mv
+
+ +

+yields a function value of type +

+ +
+func(int) int
+
+ +

+These two invocations are equivalent: +

+ +
+t.Mv(7)
+f := t.Mv; f(7)
+
+ +

+Similarly, the expression +

+ +
+pt.Mp
+
+ +

+yields a function value of type +

+ +
+func(float32) float32
+
+ +

+As with selectors, a reference to a non-interface method with a value receiver +using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. +

+ +

+As with method calls, a reference to a non-interface method with a pointer receiver +using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. +

+ +
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+
+ +

+Although the examples above use non-interface types, it is also legal to create a method value +from a value of interface type. +

+ +
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
+
+ +

Index expressions

@@ -3436,232 +3663,6 @@ channel is closed and empty.

-

Method expressions

- -

-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 ")" | "(" ReceiverType ")" .
-
- -

-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 float32) float32 { 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 five invocations are equivalent: -

- -
-t.Mv(7)
-T.Mv(t, 7)
-(T).Mv(t, 7)
-f1 := T.Mv; f1(t, 7)
-f2 := (T).Mv; f2(t, 7)
-
- -

-Similarly, the expression -

- -
-(*T).Mp
-
- -

-yields a function value representing Mp with signature -

- -
-func(tp *T, f float32) float32
-
- -

-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, a 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 -function literal or -method value. -

- -

-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. -

- -

Method values

- -

-If the expression x has static type T and -M is in the method set of type T, -x.M is called a method value. -The method value x.M is a function value that is callable -with the same arguments as a method call of x.M. -The expression x is evaluated and saved during the evaluation of the -method value; the saved copy is then used as the receiver in any calls, -which may be executed later. -

- -

-The type T may be an interface or non-interface type. -

- -

-As in the discussion of method expressions above, -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 float32) float32 { return 1 }  // pointer receiver
-
-var t T
-var pt *T
-func makeT() T
-
- -

-The expression -

- -
-t.Mv
-
- -

-yields a function value of type -

- -
-func(int) int
-
- -

-These two invocations are equivalent: -

- -
-t.Mv(7)
-f := t.Mv; f(7)
-
- -

-Similarly, the expression -

- -
-pt.Mp
-
- -

-yields a function value of type -

- -
-func(float32) float32
-
- -

-As with selectors, a reference to a non-interface method with a value receiver -using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. -

- -

-As with method calls, a reference to a non-interface method with a pointer receiver -using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. -

- -
-f := t.Mv; f(7)   // like t.Mv(7)
-f := pt.Mp; f(7)  // like pt.Mp(7)
-f := pt.Mv; f(7)  // like (*pt).Mv(7)
-f := t.Mp; f(7)   // like (&t).Mp(7)
-f := makeT().Mp   // invalid: result of makeT() is not addressable
-
- -

-Although the examples above use non-interface types, it is also legal to create a method value -from a value of interface type. -

- -
-var i interface { M(int) } = myVal
-f := i.M; f(7)  // like i.M(7)
-
-

Conversions