模块 6 · 第 3 课(共 5)课程中的28/50~10 min
模块课程(3/5)
类型开关
类型开关区分多个可能的类型
接口值。这是 comma ok 的概括,当有
不止一例。
句法
Go
func describe(i interface{}) string {
switch v := i.(type) {
case int:
return fmt.Sprintf("int %d", v)
case string:
return fmt.Sprintf("string %q", v)
case nil:
return "nil"
default:
return fmt.Sprintf("altro tipo: %T", v)
}
}i.(type)是一种 特殊语法,仅在switch内有效。v := ...将值与当前案例的类型绑定:在case int内,v具有类型int。default捕获所有其他类型;其中v具有原始接口的类型。case nil与 nil 动态类型的接口匹配。
“无名”案
如果不需要键入的值,可以省略 v:
Go
switch i.(type) {
case int:
// you know it's an int, but you don't have a variable of that type
case string:
// ...
}只需要判别类型,不需要操作时使用的一种形式 关于价值。
同一案例中的多种类型
Go
switch v := i.(type) {
case int, int64:
// here v is still interface{}: the "common" type is just the interface
fmt.Println("numero intero:", v)
case string:
// here v is string
fmt.Println("stringa:", v)
}典型用例:格式化打印
Go
func print(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("%d\n", v)
case string:
fmt.Printf("%s\n", v)
case fmt.Stringer:
fmt.Println(v.String())
default:
fmt.Printf("%v\n", v)
}
}fmt.Println 本身在内部使用类型开关来处理
标准格式。
类型开关与反射
对于一些已知类型→类型开关(快速、可读)。
用于动态检查未知类型 → reflect 包(更多
功能强大,但速度较慢且更冗长)。
尝试一下
锻炼#go.m6.l3.e1
尝试:0加载中...
实现描述(i接口{})字符串,根据动态类型返回“int”,“string”或“altro”。
正在加载编辑器...
显示提示
语法:`switch i.(type) { case T: ... default: ... }`。
3 次尝试后可用的解决方案
锻炼#go.m6.l3.e2
尝试:0加载中...
编写使用 v := i.(type) 的 printVal(i interface{}) 并用 %d 表示 int,%s 表示字符串。
正在加载编辑器...
显示提示
在 `case int` 中,v 具有 int 类型(您可以将其传递给 Printf)。
3 次尝试后可用的解决方案
Quiz#go.m6.l3.e3
准备好哪种语法启动类型切换?
Go
switch ??? {
case int: ...
}回顾
switch v := i.(type) { case T: ... }:区分动态类型。- 在单一类型的情况下,
v具有该情况的类型。 case T1, T2:v保留原始接口的类型。default用于未处理的情况;case nil用于 nil 接口。- 类型开关中没有
fallthrough。 - 1 类型 → 类型断言; 2+ 类型 → 类型开关。