From d2228692b279827a61100bbf8350688fe230448a Mon Sep 17 00:00:00 2001
From: Rob Pike
+A switch can also be used to discover the dynamic type of an interface
+variable. Such a type switch uses the syntax of a type
+assertion with the keyword type
inside the parentheses.
+If the switch declares a variable in the expression, the variable will
+have the corresponding type in each clause.
+
+switch t := interfaceValue.(type) {
+default:
+ fmt.Printf("unexpected type");
+case bool:
+ fmt.Printf("boolean %t\n", t);
+case int:
+ fmt.Printf("integer %d\n", t);
+case *bool:
+ fmt.Printf("pointer to boolean %t\n", *t);
+case *int:
+ fmt.Printf("pointer to integer %d\n", *t);
+}
+
+
Functions
Multiple return values
@@ -1350,101 +1372,9 @@ By the way, the idea of using Write
on a slice of bytes
is implemented by bytes.Buffer
.
+Library routines must often return some sort of error indication to
+the caller. As mentioned earlier, Go's multivalue return makes it
+easy to return a detailed error description alongside the normal
+return value. By convention, errors have type os.Error
,
+a simple interface.
+
+type Error interface { + String() string; +} ++
+A library writer is free to implement this interface with a
+richer model under the covers, making it possible not only
+to see the error but also to provide some context.
+For example, os.Open
returns an os.PathError
.
+
+// PathError records an error and the operation and +// file path that caused it. +type PathError struct { + Op string; // "open", "unlink", etc. + Path string; // The associated file. + Error Error; // Returned by the system call. +} + +func (e *PathError) String() string { + return e.Op + " " + e.Path + ": " + e.Error.String(); +} ++
+PathError
's String
generates
+a string like this:
+
+open /etc/passwx: no such file or directory ++
+Such an error, which includes the problematic file name, the +operation, and the operating system error it triggered, is useful even +if printed far from the call that caused it; +it is much more informative than the plain +"no such file or directory". +
+ +
+Callers that care about the precise error details can
+use a type switch or a type assertion to look for specific
+errors and extract details. For PathErrors
+this might include examining the internal Error
+field for recoverable failures.
+
+for try := 0; try < 2; try++ { + file, err := os.Open(filename, os.O_RDONLY, 0); + if err == nil { + return + } + if e, ok := err.(*os.PathError); ok && e.Error == os.ENOSPC { + deleteTempFiles(); // Recover some space. + continue + } + return +} ++ +