From afee1c5f0c1907bc575e1f87fc18889f0979cab0 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 20 Mar 2009 17:41:25 -0700 Subject: [PATCH] add simple text about & and *. clean up html: PLEASE RUN TIDY WHEN YOU EDIT THIS DOCUMENT deferring method value update until we decide what happens. R=gri DELTA=50 (38 added, 4 deleted, 8 changed) OCL=26609 CL=26612 --- doc/go_spec.html | 50 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 4100610f6c..383cae100b 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -22,7 +22,6 @@ Todo's: [ ] need to talk about precise int/floats clearly [ ] iant suggests to use abstract/precise int for len(), cap() - good idea (issue: what happens in len() + const - what is the type?) -[ ] cleanup convert() vs T() vs x.(T) - convert() should go away? [ ] fix "else" part of if statement [ ] cleanup: 6g allows: interface { f F } where F is a function type. fine, but then we should also allow: func f F {}, where F is a function type. @@ -124,6 +123,7 @@ Closed: and if so, does a label followed by an empty statement (a semicolon) still denote a for loop that is following, and can break L be used inside it? [x] there is some funniness regarding ';' and empty statements and label decls +[x] cleanup convert() vs T() vs x.(T) - convert() should go away? --> @@ -1403,7 +1403,6 @@ Constants: Functions: cap len make new panic panicln print println - (TODO: typeof??) Packages: sys (TODO: does sys endure?) @@ -2664,17 +2663,30 @@ The right operand is evaluated conditionally.

Address operators

- -

-TODO: Need to talk about unary "*", clean up section below. +The unary prefix address-of operator & 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)
+
+

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

 type T struct {
@@ -2684,25 +2696,33 @@ 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;
@@ -2710,30 +2730,39 @@ 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;
@@ -2743,8 +2772,10 @@ 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) {
@@ -2752,13 +2783,16 @@ func (recv I, a int) {
 }
 
+

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?) +

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

Predeclared functions

Length and capacity

-- 2.48.1