diff --git a/doc/effective_go.html b/doc/effective_go.html index becfd17b2a..bdea687f1f 100644 --- a/doc/effective_go.html +++ b/doc/effective_go.html @@ -618,31 +618,112 @@ func Compare(a, b []byte) int { } +
+One of Go's unusual properties is that functions and methods
+can return multiple values. This feature can be used to
+improve on a couple of clumsy idioms in C program: in-band
+error returns (-1 for EOF for example)
+and modifying an argument.
+
+In C, a write error is signaled by a negative byte count with the
+error code secreted away in a volatile location.
+In Go, Write
+can return a byte count and an error: "Yes, you wrote some
+bytes but not all of them because you filled the device".
+The signature of *File.Write in package os is:
+
+func (file *File) Write(b []byte) (n int, err Error) ++ +
+and as the documentation says, it returns the number of bytes
+written and a non-nil Error when n
+!= len(b).
+This is a common style; see the section on error handling for more examples.
+
+A similar approach obviates the need to pass a pointer to a return +value to overwrite an argument. Here's a simple-minded function to +grab a number from a position in a byte array, returning the number +and the next position. +
+ +
+func nextInt(b []byte, i int) (int, int) {
+ for ; i < len(b) && !isDigit(b[i]); i++ {
+ }
+ x := 0;
+ for ; i < len(b) && isDigit(b[i]); i++ {
+ x = x*10 + int(b[i])-'0'
+ }
+ return x, i;
+}
+
+
+
+You could use it to scan the numbers in an input array a like this:
+
+ for i := 0; i < len(a); {
+ x, i = nextInt(a, i);
+ fmt.Println(x);
+ }
+
+
+
+The return or result "parameters" of a Go function can be given names and
+used as regular variables, just like the incoming parameters.
+When named, they are initialized to the zero for their type when
+the function begins; if the function executes a return statement
+with no arguments, the current values of the result parameters are
+used as the returned values.
+
+The names are not mandatory but they can make code shorter and clearer:
+they're documentation.
+If we name the results of nextInt it becomes
+obvious which returned int
+is which.
+
+func nextInt(b []byte, pos int) (value, nextPos int) {
+
+
+
+Because named results are initialized and tied to an unadorned return, they can simplify
+as well as clarify. Here's a version
+of io.ReadFull that uses them well:
+
+func ReadFull(r Reader, buf []byte) (n int, err os.Error) {
+ for len(buf) > 0 && err != nil {
+ var nr int;
+ nr, err = r.Read(buf);
+ n += nr;
+ buf = buf[nr:len(buf)];
+ }
+ return;
+}
+
+