Spec: http://golang.org/doc/go_spec.html#Switch_statements
Go‘s switch
statements are pretty neat. For one thing, you don’t need to break at the end of each case.
switch c { case '&': esc = "&" case '\'': esc = "'" case '<': esc = "<" case '>': esc = ">" case '"': esc = """ default: panic("unrecognized escape character") }
Switches work on values of any type.
switch syscall.OS { case "windows": sd = &sysDir{ Getenv("SystemRoot") + `\system32\drivers\etc`, []string{ "hosts", "networks", "protocol", "services", }, } case "plan9": sd = &sysDir{ "/lib/ndb", []string{ "common", "local", }, } default: sd = &sysDir{ "/etc", []string{ "group", "hosts", "passwd", }, } }
In fact, you don't need to switch on anything at all. A switch with no value means “switch true”, making it a cleaner version of an if-else chain, as in this example from Effective Go:
func unhex(c byte) byte { switch { case '0' <= c && c <= '9': return c - '0' case 'a' <= c && c <= 'f': return c - 'a' + 10 case 'A' <= c && c <= 'F': return c - 'A' + 10 } return 0 }
Go's switch
statements break
implicitly, but break
is still useful:
command := ReadCommand() argv := strings.Fields(command) switch argv[0] { case "echo": fmt.Print(argv[1:]...) case "cat": if len(argv) <= 1 { fmt.Println("Usage: cat <filename>") break } PrintFile(argv[1]) default: fmt.Println("Unknown command; try 'echo' or 'cat'") }
To fall through to a subsequent case, use the fallthrough
keyword:
// Unpack 4 bytes into uint32 to repack into base 85 5-byte. var v uint32 switch len(src) { default: v |= uint32(src[3]) fallthrough case 3: v |= uint32(src[2]) << 8 fallthrough case 2: v |= uint32(src[1]) << 16 fallthrough case 1: v |= uint32(src[0]) << 24 }
src/pkg/encoding/ascii85/ascii85.go
The ‘fallthrough’ must be the last thing in the case; you can't write something like
switch { case f(): if g() { fallthrough // Does not work! } h() default: error() }
If you want to use multiple values in the same case, use a comma-separated list.
func letterOp(code int) bool { switch chars[code].category { case "Lu", "Ll", "Lt", "Lm", "Lo": return true } return false }
With a type switch you can switch on the type of an interface value (only):
func typeName(v interface{}) string { switch v.(type) { case int: return "int" case string: return "string" default: return "unknown" } panic("unreachable") }
You can also declare a variable and it will have the type of each case
:
func do(v interface{}) string { switch u := v.(type) { case int: return strconv.Itoa(u*2) // u has type int case string: mid := len(u) / 2 // split - u has type string return u[mid:] + u[:mid] // join } return "unknown" } do(21) == "42" do("bitrab") == "rabbit" do(3.142) == "unknown"