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,75 +1372,124 @@ By the way, the idea of using Write
on a slice of bytes
is implemented by bytes.Buffer
.
os.Error
should
-describe the error and provide context.
-For example, os.Open
returns an os.PathError
:
+
+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; - Path string; - Error Error; + 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(); + return e.Op + " " + e.Path + ": " + e.Error.String(); }-
-PathError
's String
formats
-the error nicely, including the operation and file name
-tha failed; just printing the error generates a
-message, such as
+PathError
's String
generates
+a string like this:
open /etc/passwx: no such file or directory
-that is useful even if printed far from the call that -triggered it. +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 guard to look for specific
+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
-to see if it is os.EPERM
or os.ENOENT
,
-for instance.
+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 +} ++ +