Go type switch的四种用法小结
作者:运维开发笔记
1. type switch 基本语法 — switch value.(type)
type switch 根据 interface{} 值的实际类型进行分支判断,类似"类型版"的 switch:
package main
import "fmt"
func describeType(value interface{}) {
switch value.(type) {
case string:
v := value.(string)
fmt.Println("It's a string with length:", len(v))
case int:
v := value.(int)
fmt.Println("It's an integer with value:", v)
case bool:
v := value.(bool)
fmt.Println("It's a boolean with value:", v)
case []int:
v := value.([]int)
fmt.Println("It's an int slice with length:", len(v))
default:
fmt.Println("Unknown type")
}
}
func main() {
fmt.Println("=== describeType tests ===")
describeType("hello world")
describeType(42)
describeType(true)
describeType([]int{1, 2, 3, 4, 5})
describeType(3.14)
}
执行结果:
=== describeType tests ===
It's a string with length: 11
It's an integer with value: 42
It's a boolean with value: true
It's an int slice with length: 5
Unknown type
要点:
- switch value.(type) — 注意是 .(type) 不是 .(Type),type 是关键字
- 每个 case 匹配一个具体类型:case string、case int、case bool 等
- 匹配后需要手动断言获取值:v := value.(string) — 在 type switch 中这种写法可行,但更推荐用变量赋值写法(知识点 2)
- default 处理所有未匹配的类型:3.14 是 float64,没有 case float64,所以走 default
- .(type) 只能在 switch 语句中使用,不能单独写 value.(type)(编译报错)
2. type switch 变量赋值 — switch v := value.(type)
推荐写法:在 switch 中直接声明变量 v,v 在每个 case 分支中自动具有对应类型,无需手动断言:
package main
import (
"fmt"
"reflect"
)
func processValue(value interface{}) {
switch v := value.(type) {
case string:
// v 自动是 string 类型,可以直接使用 len(v) 等字符串操作
if len(v) > 5 {
fmt.Println("Long string:", v)
} else {
fmt.Println("Short string:", v)
}
case int:
// v 自动是 int 类型,可以直接做数值运算
if v > 0 {
fmt.Println("Positive:", v)
} else {
fmt.Println("Non-positive:", v)
}
case float64:
// v 自动是 float64 类型
fmt.Printf("Float with 2 decimal places: %.2f\n", v)
default:
// v 是 interface{} 类型,需要用 reflect 获取类型信息
fmt.Println("Cannot process type:", reflect.TypeOf(value))
}
}
func main() {
fmt.Println("=== processValue tests ===")
processValue("short")
processValue("this is a long string")
processValue(-10)
processValue(25)
processValue(3.14159)
processValue([]string{"not", "handled"})
}
执行结果:
=== processValue tests ===
Short string: short
Long string: this is a long string
Non-positive: -10
Positive: 25
Float with 2 decimal places: 3.14
Cannot process type: []string
要点:
- switch v := value.(type) — v 在每个 case 中自动具有该 case 对应的类型:
- case string: 中 v 是 string,可以直接 len(v)
- case int: 中 v 是 int,可以直接 v > 0
- case float64: 中 v 是 float64,可以直接 %.2f 格式化
- default: 中 v 是 interface{}
- 对比知识点 1 的写法:手动断言 v := value.(string) vs 自动推断 v := value.(type),后者更简洁安全
- reflect.TypeOf(value) 在 default 中获取值的实际类型名称(输出 “[]string”)
- 这是 Go 处理未知类型数据的标准模式
3. type switch 处理接口类型 — 匹配 error 接口
type switch 的 case 不仅可以是具体类型(string、int),还可以是接口类型(error、io.Reader 等):
package main
import "fmt"
func handleError(value interface{}) {
switch v := value.(type) {
case string:
fmt.Println("String error:", v)
case error:
fmt.Println("Error type:", v.Error())
case nil:
fmt.Println("No error")
default:
fmt.Println("Unknown error type")
}
}
func main() {
fmt.Println("=== handleError tests ===")
handleError("file not found")
handleError(fmt.Errorf("custom error"))
handleError(nil)
handleError(123)
}
执行结果:
=== handleError tests ===
String error: file not found
Error type: custom error
No error
Unknown error type
要点:
- case error: — 匹配所有实现了 error 接口的类型(如 fmt.Errorf 返回的 *errors.errorString)
- case nil: — 匹配 nil 值,专门处理"无错误"的情况
- 匹配顺序:string 是具体类型,error 是接口类型。如果一个值既是 string 又实现了 error(理论上不可能),具体类型优先
- fmt.Errorf(“custom error”) 返回的是 *errors.errorString 类型,它实现了 error 接口的 Error() 方法
- 实际场景:处理多种错误类型时,先匹配具体错误类型,再匹配通用 error 接口,最后 default 兜底
4. type switch 多类型合并 — 一个 case 匹配多种类型
多个类型可以写在同一个 case 中,用逗号分隔:
package main
import "fmt"
func main() {
fmt.Println("=== Multiple types in one case ===")
handleInteger := func(value interface{}) {
switch v := value.(type) {
case int, int32, int64:
fmt.Printf("Integer type value: %v (type: %T)\n", v, v)
default:
fmt.Println("Not an integer type")
}
}
handleInteger(10)
handleInteger(int32(20))
handleInteger(int64(30))
handleInteger("not an integer")
}
执行结果:
=== Multiple types in one case ===
Integer type value: 10 (type: int)
Integer type value: 20 (type: int32)
Integer type value: 30 (type: int64)
Not an integer type
要点:
- case int, int32, int64: — 三种整数类型合并为一个 case
- 注意:合并 case 时,v 的类型是 interface{},不是具体类型!因为编译器无法确定 v 到底是 int 还是 int32
- 所以在合并 case 中不能直接对 v 数值运算(v + 1 编译报错),需要用 %v 和 %T 输出
- %T 格式化动词输出变量的实际类型(int、int32、int64)
- %v 格式化动词输出变量的默认值表示
- 如果需要对合并类型做运算,需要单独写 case 或在 case 内再做一次断言
知识点总结
| 知识点 | 关键概念 |
| type switch 基本语法 | switch value.(type) |
| 变量赋值写法 | switch v := value.(type) |
| 匹配接口类型 | case error: |
| 多类型合并 | case int, int32, int64: |
| .(type) 限制 | .(type) |
到此这篇关于Go type switch的四种用法小结的文章就介绍到这了,更多相关Go type switch用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
