From 6e15683caee9085dfc953c39a49f13ccc9dc1c86 Mon Sep 17 00:00:00 2001
From: Russ Cox x.f is illegal.
x is of pointer or interface type and has the value
-nil, assigning to, evaluating, or calling x.f
+If x is of pointer type and has the value
+nil and x.f denotes a struct field,
+assigning to or evaluating x.f
+causes a run-time panic.
+x is of interface type and has the value
+nil, calling or
+evaluating the method x.f
causes a run-time panic.
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.
+function literal or
+method value.
@@ -3442,6 +3451,111 @@ 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.
+
+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.Mv is equivalent to (&t).Mv.
+
+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)
+
+
-- 2.52.0