/* 03-type-assertions.go - Go 语言类型断言详解 学习目标: 1. 掌握类型断言的语法和用法 2. 理解类型断言的安全性 3. 学会类型 switch 的使用 4. 了解接口类型断言的应用 5. 掌握类型断言的最佳实践 知识点: - 类型断言的基本语法 - 安全类型断言 vs 不安全类型断言 - 类型 switch 语句 - 接口到具体类型的断言 - 接口到接口的断言 - 类型断言的性能考虑 - 类型断言的实际应用场景 */ package main import ( "fmt" "io" "strings" ) func main() { fmt.Println("=== Go 语言类型断言详解 ===\\n") // 演示基本类型断言 demonstrateBasicTypeAssertions() // 演示安全 vs 不安全类型断言 demonstrateSafeVsUnsafeAssertions() // 演示类型 switch demonstrateTypeSwitchExamples() // 演示接口类型断言 demonstrateInterfaceAssertions() // 演示类型断言的实际应用 demonstratePracticalApplications() // 演示类型断言的高级用法 demonstrateAdvancedUsageExamples() // 演示类型断言的最佳实践 demonstrateBestPracticesExamples() } // demonstrateBasicTypeAssertions 演示基本类型断言 func demonstrateBasicTypeAssertions() { fmt.Println("1. 基本类型断言:") // 类型断言的基本语法 fmt.Printf(" 类型断言的基本语法:\\n") fmt.Printf(" value.(Type) - 不安全断言,失败时 panic\\n") fmt.Printf(" value, ok := value.(Type) - 安全断言,返回值和布尔标志\\n") // 基本类型断言示例 fmt.Printf(" 基本类型断言示例:\\n") var value interface{} = "Hello, World!" // 安全的类型断言 if str, ok := value.(string); ok { fmt.Printf(" 字符串断言成功: \\\"%s\\\" (长度: %d)\\n", str, len(str)) } else { fmt.Printf(" 字符串断言失败\\n") } // 断言为整数(会失败) if num, ok := value.(int); ok { fmt.Printf(" 整数断言成功: %d\\n", num) } else { fmt.Printf(" 整数断言失败,实际类型: %T\\n", value) } // 不同类型的断言 fmt.Printf(" 不同类型的断言:\\n") values := []interface{}{ 42, 3.14159, true, "Go语言", []int{1, 2, 3}, map[string]int{"key": 100}, Person{Name: "Alice", Age: 30}, } for i, v := range values { fmt.Printf(" 值 %d (%v):\\n", i+1, v) // 尝试断言为不同类型 if intVal, ok := v.(int); ok { fmt.Printf(" -> 整数: %d\\n", intVal) } else if floatVal, ok := v.(float64); ok { fmt.Printf(" -> 浮点数: %.3f\\n", floatVal) } else if boolVal, ok := v.(bool); ok { fmt.Printf(" -> 布尔值: %t\\n", boolVal) } else if strVal, ok := v.(string); ok { fmt.Printf(" -> 字符串: \\\"%s\\\"\\n", strVal) } else { fmt.Printf(" -> 其他类型: %T\\n", v) } } fmt.Println() } // demonstrateSafeVsUnsafeAssertions 演示安全 vs 不安全类型断言 func demonstrateSafeVsUnsafeAssertions() { fmt.Println("2. 安全 vs 不安全类型断言:") // 安全类型断言 fmt.Printf(" 安全类型断言 (推荐):\\n") var value interface{} = 42 // 安全断言 - 返回值和布尔标志 if str, ok := value.(string); ok { fmt.Printf(" 字符串断言成功: %s\\n", str) } else { fmt.Printf(" 字符串断言失败,实际类型: %T,值: %v\\n", value, value) } if num, ok := value.(int); ok { fmt.Printf(" 整数断言成功: %d\\n", num) } else { fmt.Printf(" 整数断言失败\\n") } // 不安全类型断言 fmt.Printf(" 不安全类型断言 (谨慎使用):\\n") // 成功的不安全断言 num := value.(int) fmt.Printf(" 不安全整数断言成功: %d\\n", num) // 失败的不安全断言(会 panic) fmt.Printf(" 演示不安全断言的 panic 风险:\\n") // 使用 defer 和 recover 捕获 panic func() { defer func() { if r := recover(); r != nil { fmt.Printf(" 捕获到 panic: %v\\n", r) } }() // 这会导致 panic str := value.(string) fmt.Printf(" 不安全字符串断言: %s\\n", str) }() // 安全断言的实际应用 fmt.Printf(" 安全断言的实际应用:\\n") data := []interface{}{ "hello", 42, 3.14, true, nil, } for i, item := range data { fmt.Printf(" 处理项目 %d:\\n", i+1) processItemSafely(item) } fmt.Println() } // demonstrateTypeSwitchExamples 演示类型 switch func demonstrateTypeSwitchExamples() { fmt.Println("3. 类型 switch:") fmt.Printf(" 类型 switch 是处理多种类型的优雅方式\\n") // 基本类型 switch fmt.Printf(" 基本类型 switch:\\n") values := []interface{}{ 42, "Hello", 3.14159, true, []int{1, 2, 3}, map[string]int{"a": 1, "b": 2}, Person{Name: "Alice", Age: 30}, &Person{Name: "Bob", Age: 25}, nil, } for i, value := range values { fmt.Printf(" 值 %d: ", i+1) processWithTypeSwitch(value) } // 类型 switch 的高级用法 fmt.Printf(" 类型 switch 的高级用法:\\n") // 处理不同的数值类型 numbers := []interface{}{ int(42), int8(8), int16(16), int32(32), int64(64), uint(42), float32(3.14), float64(2.718), } fmt.Printf(" 数值类型处理:\\n") for _, num := range numbers { result := convertToFloat64(num) fmt.Printf(" %v (%T) -> %.3f\\n", num, num, result) } // 类型 switch 与接口 fmt.Printf(" 类型 switch 与接口:\\n") shapes := []Shape{ Circle{Radius: 5}, Rectangle{Width: 4, Height: 6}, Triangle{Base: 8, Height: 6}, } for i, shape := range shapes { fmt.Printf(" 形状 %d: ", i+1) describeShape(shape) } fmt.Println() } // demonstrateInterfaceAssertions 演示接口类型断言 func demonstrateInterfaceAssertions() { fmt.Println("4. 接口类型断言:") // 接口到具体类型的断言 fmt.Printf(" 接口到具体类型的断言:\\n") var shape Shape = Circle{Radius: 5} // 断言为具体类型 if circle, ok := shape.(Circle); ok { fmt.Printf(" 断言为圆形成功: 半径 = %.1f\\n", circle.Radius) fmt.Printf(" 圆形面积: %.2f\\n", circle.Area()) fmt.Printf(" 圆形周长: %.2f\\n", circle.Perimeter()) } if rect, ok := shape.(Rectangle); ok { fmt.Printf(" 断言为矩形成功: %dx%d\\n", int(rect.Width), int(rect.Height)) } else { fmt.Printf(" 断言为矩形失败,实际类型: %T\\n", shape) } // 接口到接口的断言 fmt.Printf(" 接口到接口的断言:\\n") var writer io.Writer = &strings.Builder{} // 断言为更具体的接口 if stringWriter, ok := writer.(io.StringWriter); ok { fmt.Printf(" 支持 StringWriter 接口\\n") n, err := stringWriter.WriteString("Hello, Interface!") if err == nil { fmt.Printf(" 写入字符串成功: %d 字节\\n", n) } } // 检查接口是否支持其他方法 if closer, ok := writer.(io.Closer); ok { fmt.Printf(" 支持 Closer 接口\\n") closer.Close() } else { fmt.Printf(" 不支持 Closer 接口\\n") } // 多接口断言 fmt.Printf(" 多接口断言:\\n") var device Device = &NetworkDevice{ name: "路由器", address: "192.168.1.1", } // 检查设备支持的接口 fmt.Printf(" 设备: %s\\n", device.GetName()) if networkable, ok := device.(Networkable); ok { fmt.Printf(" 支持网络功能: %s\\n", networkable.GetAddress()) } if configurable, ok := device.(Configurable); ok { config := configurable.GetConfig() fmt.Printf(" 支持配置功能: %v\\n", config) } if manageable, ok := device.(Manageable); ok { status := manageable.GetStatus() fmt.Printf(" 支持管理功能: %s\\n", status) } fmt.Println() } // demonstratePracticalApplications 演示类型断言的实际应用 func demonstratePracticalApplications() { fmt.Println("5. 类型断言的实际应用:") // 应用1: 错误处理 fmt.Printf(" 应用1 - 错误处理:\\n") errors := []error{ &ValidationError{Field: "email", Message: "无效的邮箱格式"}, &NetworkError{Code: 500, Message: "服务器内部错误"}, fmt.Errorf("普通错误"), } for i, err := range errors { fmt.Printf(" 错误 %d: ", i+1) handleError(err) } // 应用2: 插件系统 fmt.Printf(" 应用2 - 插件系统:\\n") plugins := []Plugin{ &LoggingPlugin{Level: "INFO"}, &CachePlugin{Size: 1000}, &SecurityPlugin{Enabled: true}, } pluginManager := PluginManager{plugins: plugins} pluginManager.ExecuteAll("测试数据") // 应用3: 数据序列化 fmt.Printf(" 应用3 - 数据序列化:\\n") serializer := DataSerializer{} data := []interface{}{ Person{Name: "Alice", Age: 30}, &Person{Name: "Bob", Age: 25}, []int{1, 2, 3, 4, 5}, map[string]interface{}{ "name": "Charlie", "age": 35, }, } for i, item := range data { serialized := serializer.Serialize(item) fmt.Printf(" 数据 %d: %s\\n", i+1, serialized) } // 应用4: 类型转换器 fmt.Printf(" 应用4 - 类型转换器:\\n") converter := TypeConverter{} values := []interface{}{ 42, "123", 3.14, true, "false", } for _, value := range values { strResult := converter.ToString(value) intResult := converter.ToInt(value) boolResult := converter.ToBool(value) fmt.Printf(" %v (%T):\\n", value, value) fmt.Printf(" -> 字符串: \\\"%s\\\"\\n", strResult) fmt.Printf(" -> 整数: %d\\n", intResult) fmt.Printf(" -> 布尔值: %t\\n", boolResult) } fmt.Println() } // demonstrateAdvancedUsageExamples 演示类型断言的高级用法 func demonstrateAdvancedUsageExamples() { fmt.Println("6. 类型断言的高级用法:") // 高级用法1: 链式类型断言 fmt.Printf(" 高级用法1 - 链式类型断言:\\n") var value interface{} = &strings.Builder{} // 链式断言检查多个接口 if writer, ok := value.(io.Writer); ok { fmt.Printf(" 支持 Writer 接口\\n") if stringWriter, ok := writer.(io.StringWriter); ok { fmt.Printf(" 同时支持 StringWriter 接口\\n") stringWriter.WriteString("链式断言测试") } if stringer, ok := writer.(fmt.Stringer); ok { fmt.Printf(" 同时支持 Stringer 接口: %s\\n", stringer.String()) } } // 高级用法2: 类型断言与反射结合 fmt.Printf(" 高级用法2 - 类型断言与反射结合:\\n") inspector := TypeInspector{} testValues := []interface{}{ Person{Name: "Alice", Age: 30}, &Person{Name: "Bob", Age: 25}, []Person{{Name: "Charlie", Age: 35}}, map[string]Person{"key": {Name: "David", Age: 40}}, } for i, value := range testValues { fmt.Printf(" 检查值 %d:\\n", i+1) inspector.InspectWithAssertion(value) } // 高级用法3: 动态方法调用 fmt.Printf(" 高级用法3 - 动态方法调用:\\n") objects := []interface{}{ &Calculator{}, &Formatter{}, &Validator{}, } for i, obj := range objects { fmt.Printf(" 对象 %d:\\n", i+1) callMethodsDynamically(obj) } // 高级用法4: 接口适配器模式 fmt.Printf(" 高级用法4 - 接口适配器模式:\\n") // 旧接口实现 oldLogger := &OldLogger{} // 使用适配器 var newLogger Logger = &LoggerAdapter{oldLogger: oldLogger} newLogger.Log("这是通过适配器记录的日志") // 检查适配器是否支持额外功能 if advancedLogger, ok := newLogger.(AdvancedLogger); ok { advancedLogger.LogWithContext("错误消息", map[string]string{ "user_id": "123", "action": "login", }) } fmt.Println() } // demonstrateBestPracticesExamples 演示类型断言的最佳实践 func demonstrateBestPracticesExamples() { fmt.Println("7. 类型断言的最佳实践:") fmt.Printf(" 最佳实践原则:\\n") fmt.Printf(" 1. 总是使用安全的类型断言(检查 ok 值)\\n") fmt.Printf(" 2. 优先使用类型 switch 处理多种类型\\n") fmt.Printf(" 3. 在断言失败时提供有意义的错误处理\\n") fmt.Printf(" 4. 避免过深的类型断言链\\n") fmt.Printf(" 5. 考虑使用接口而不是具体类型断言\\n") // 最佳实践示例 fmt.Printf(" 最佳实践示例:\\n") // 1. 安全的类型断言 fmt.Printf(" 1. 安全的类型断言:\\n") var data interface{} = "test data" result, err := safeStringAssertion(data) if err != nil { fmt.Printf(" 断言失败: %v\\n", err) } else { fmt.Printf(" 断言成功: %s\\n", result) } // 2. 优雅的错误处理 fmt.Printf(" 2. 优雅的错误处理:\\n") values := []interface{}{ "valid string", 42, nil, } for i, value := range values { result, err := safeStringAssertion(value) fmt.Printf(" 值 %d: ", i+1) if err != nil { fmt.Printf("错误 - %v\\n", err) } else { fmt.Printf("成功 - \\\"%s\\\"\\n", result) } } // 3. 接口优先的设计 fmt.Printf(" 3. 接口优先的设计:\\n") // 好的做法:依赖接口而不是具体类型 var processor DataProcessor = &JSONProcessor{} // 检查是否支持额外功能 if validator, ok := processor.(DataValidator); ok { fmt.Printf(" 处理器支持数据验证\\n") isValid := validator.Validate(`{"name": "Alice"}`) fmt.Printf(" 数据验证结果: %t\\n", isValid) } if formatter, ok := processor.(DataFormatter); ok { fmt.Printf(" 处理器支持数据格式化\\n") formatted := formatter.Format(`{"name":"Alice","age":30}`) fmt.Printf(" 格式化结果: %s\\n", formatted) } // 4. 性能考虑 fmt.Printf(" 4. 性能考虑:\\n") fmt.Printf(" - 类型断言有运行时开销\\n") fmt.Printf(" - 在热点代码中谨慎使用\\n") fmt.Printf(" - 考虑缓存断言结果\\n") fmt.Printf(" - 优先使用具体类型而不是接口\\n") // 5. 常见陷阱 fmt.Printf(" 5. 避免常见陷阱:\\n") fmt.Printf(" - 不要忽略断言的 ok 返回值\\n") fmt.Printf(" - 注意 nil 接口的断言行为\\n") fmt.Printf(" - 理解接口的动态类型和动态值\\n") fmt.Printf(" - 避免对 nil 值进行类型断言\\n") // 演示 nil 接口断言 var nilInterface interface{} if str, ok := nilInterface.(string); ok { fmt.Printf(" nil 断言成功: %s\\n", str) } else { fmt.Printf(" nil 接口断言失败(正确行为)\\n") } fmt.Println() } / / ========== 类型定义 ========== // 基本结构体 type Person struct { Name string Age int } // 几何图形接口和实现 type Shape interface { Area() float64 Perimeter() float64 } type Circle struct { Radius float64 } func (c Circle) Area() float64 { return 3.14159 * c.Radius * c.Radius } func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius } type Rectangle struct { Width, Height float64 } func (r Rectangle) Area() float64 { return r.Width * r.Height } func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) } type Triangle struct { Base, Height float64 } func (t Triangle) Area() float64 { return 0.5 * t.Base * t.Height } func (t Triangle) Perimeter() float64 { // 假设是等腰三角形 side := (t.Base*t.Base + 4*t.Height*t.Height) / (2 * t.Base) return t.Base + 2*side } // 设备接口系统 type Device interface { GetName() string } type Networkable interface { GetAddress() string } type Configurable interface { GetConfig() map[string]string } type Manageable interface { GetStatus() string } type NetworkDevice struct { name string address string } func (nd *NetworkDevice) GetName() string { return nd.name } func (nd *NetworkDevice) GetAddress() string { return nd.address } func (nd *NetworkDevice) GetConfig() map[string]string { return map[string]string{ "ip": nd.address, "type": "network", } } func (nd *NetworkDevice) GetStatus() string { return "online" } // 错误类型 type ValidationError struct { Field string Message string } func (ve *ValidationError) Error() string { return fmt.Sprintf("验证错误 [%s]: %s", ve.Field, ve.Message) } type NetworkError struct { Code int Message string } func (ne *NetworkError) Error() string { return fmt.Sprintf("网络错误 [%d]: %s", ne.Code, ne.Message) } // 插件系统 type Plugin interface { Execute(data string) string } type LoggingPlugin struct { Level string } func (lp *LoggingPlugin) Execute(data string) string { return fmt.Sprintf("[%s] 日志: %s", lp.Level, data) } type CachePlugin struct { Size int } func (cp *CachePlugin) Execute(data string) string { return fmt.Sprintf("缓存 (大小:%d): %s", cp.Size, data) } type SecurityPlugin struct { Enabled bool } func (sp *SecurityPlugin) Execute(data string) string { if sp.Enabled { return fmt.Sprintf("安全检查通过: %s", data) } return fmt.Sprintf("安全检查跳过: %s", data) } type PluginManager struct { plugins []Plugin } func (pm *PluginManager) ExecuteAll(data string) { for i, plugin := range pm.plugins { result := plugin.Execute(data) fmt.Printf(" 插件 %d 结果: %s\\n", i+1, result) } } // 数据序列化器 type DataSerializer struct{} func (ds DataSerializer) Serialize(data interface{}) string { switch v := data.(type) { case Person: return fmt.Sprintf("Person{Name:%s,Age:%d}", v.Name, v.Age) case *Person: return fmt.Sprintf("*Person{Name:%s,Age:%d}", v.Name, v.Age) case []int: return fmt.Sprintf("[]int%v", v) case map[string]interface{}: return fmt.Sprintf("map%v", v) default: return fmt.Sprintf("%T(%v)", v, v) } } // 类型转换器 type TypeConverter struct{} func (tc TypeConverter) ToString(value interface{}) string { switch v := value.(type) { case string: return v case int: return strconv.Itoa(v) case float64: return strconv.FormatFloat(v, 'f', -1, 64) case bool: return strconv.FormatBool(v) default: return fmt.Sprintf("%v", v) } } func (tc TypeConverter) ToInt(value interface{}) int { switch v := value.(type) { case int: return v case string: if num, err := strconv.Atoi(v); err == nil { return num } case float64: return int(v) case bool: if v { return 1 } return 0 } return 0 } func (tc TypeConverter) ToBool(value interface{}) bool { switch v := value.(type) { case bool: return v case string: return v == "true" case int: return v != 0 case float64: return v != 0.0 } return false } // 类型检查器 type TypeInspector struct{} func (ti TypeInspector) InspectWithAssertion(value interface{}) { // 使用类型断言检查不同类型 if person, ok := value.(Person); ok { fmt.Printf(" Person 值类型: %s, %d岁\\n", person.Name, person.Age) } else if personPtr, ok := value.(*Person); ok { fmt.Printf(" Person 指针类型: %s, %d岁\\n", personPtr.Name, personPtr.Age) } else if personSlice, ok := value.([]Person); ok { fmt.Printf(" Person 切片类型: %d 个元素\\n", len(personSlice)) } else if personMap, ok := value.(map[string]Person); ok { fmt.Printf(" Person 映射类型: %d 个键值对\\n", len(personMap)) } else { fmt.Printf(" 未知类型: %T\\n", value) } } // 动态方法调用相关类型 type Calculator struct{} func (c *Calculator) Add(a, b int) int { return a + b } func (c *Calculator) GetType() string { return "Calculator" } type Formatter struct{} func (f *Formatter) Format(text string) string { return fmt.Sprintf("[格式化] %s", text) } func (f *Formatter) GetType() string { return "Formatter" } type Validator struct{} func (v *Validator) Validate(data string) bool { return len(data) > 0 } func (v *Validator) GetType() string { return "Validator" } // 日志系统 type Logger interface { Log(message string) } type AdvancedLogger interface { LogWithContext(message string, context map[string]string) } type OldLogger struct{} func (ol *OldLogger) WriteLog(level, message string) { fmt.Printf(" [旧日志系统] %s: %s\\n", level, message) } type LoggerAdapter struct { oldLogger *OldLogger } func (la *LoggerAdapter) Log(message string) { la.oldLogger.WriteLog("INFO", message) } func (la *LoggerAdapter) LogWithContext(message string, context map[string]string) { contextStr := "" for k, v := range context { contextStr += fmt.Sprintf("%s=%s ", k, v) } la.oldLogger.WriteLog("ERROR", fmt.Sprintf("%s [%s]", message, contextStr)) } // 数据处理器接口 type DataProcessor interface { Process(data string) string } type DataValidator interface { Validate(data string) bool } type DataFormatter interface { Format(data string) string } type JSONProcessor struct{} func (jp *JSONProcessor) Process(data string) string { return fmt.Sprintf("处理JSON: %s", data) } func (jp *JSONProcessor) Validate(data string) bool { // 简单的JSON验证 return strings.HasPrefix(data, "{") && strings.HasSuffix(data, "}") } func (jp *JSONProcessor) Format(data string) string { // 简单的JSON格式化 return strings.ReplaceAll(data, ",", ", ") } // ========== 辅助函数 ========== // 安全处理项目 func processItemSafely(item interface{}) { switch v := item.(type) { case nil: fmt.Printf(" nil 值\\n") case string: fmt.Printf(" 字符串: \\\"%s\\\" (长度: %d)\\n", v, len(v)) case int: fmt.Printf(" 整数: %d\\n", v) case float64: fmt.Printf(" 浮点数: %.3f\\n", v) case bool: fmt.Printf(" 布尔值: %t\\n", v) default: fmt.Printf(" 其他类型: %T, 值: %v\\n", v, v) } } // 使用类型 switch 处理值 func processWithTypeSwitch(value interface{}) { switch v := value.(type) { case nil: fmt.Printf("nil 值\\n") case int: fmt.Printf("整数: %d\\n", v) case string: fmt.Printf("字符串: \\\"%s\\\" (长度: %d)\\n", v, len(v)) case float64: fmt.Printf("浮点数: %.3f\\n", v) case bool: fmt.Printf("布尔值: %t\\n", v) case []int: fmt.Printf("整数切片: %v (长度: %d)\\n", v, len(v)) case map[string]int: fmt.Printf("字符串到整数的映射: %v (大小: %d)\\n", v, len(v)) case Person: fmt.Printf("Person 结构体: %s (%d岁)\\n", v.Name, v.Age) case *Person: fmt.Printf("Person 指针: %s (%d岁)\\n", v.Name, v.Age) default: fmt.Printf("未知类型: %T, 值: %v\\n", v, v) } } // 转换为 float64 func convertToFloat64(value interface{}) float64 { switch v := value.(type) { case int: return float64(v) case int8: return float64(v) case int16: return float64(v) case int32: return float64(v) case int64: return float64(v) case uint: return float64(v) case float32: return float64(v) case float64: return v default: return 0.0 } } // 描述形状 func describeShape(shape Shape) { area := shape.Area() perimeter := shape.Perimeter() switch s := shape.(type) { case Circle: fmt.Printf("圆形 (半径: %.1f) - 面积: %.2f, 周长: %.2f\\n", s.Radius, area, perimeter) case Rectangle: fmt.Printf("矩形 (%.1fx%.1f) - 面积: %.2f, 周长: %.2f\\n", s.Width, s.Height, area, perimeter) case Triangle: fmt.Printf("三角形 (底: %.1f, 高: %.1f) - 面积: %.2f, 周长: %.2f\\n", s.Base, s.Height, area, perimeter) default: fmt.Printf("未知形状 - 面积: %.2f, 周长: %.2f\\n", area, perimeter) } } // 处理错误 func handleError(err error) { switch e := err.(type) { case *ValidationError: fmt.Printf("验证错误 - 字段: %s, 消息: %s\\n", e.Field, e.Message) case *NetworkError: fmt.Printf("网络错误 - 代码: %d, 消息: %s\\n", e.Code, e.Message) default: fmt.Printf("普通错误: %s\\n", err.Error()) } } // 动态调用方法 func callMethodsDynamically(obj interface{}) { // 检查对象类型并调用相应方法 switch o := obj.(type) { case *Calculator: fmt.Printf(" %s: 10 + 20 = %d\\n", o.GetType(), o.Add(10, 20)) case *Formatter: fmt.Printf(" %s: %s\\n", o.GetType(), o.Format("测试文本")) case *Validator: fmt.Printf(" %s: 验证 'test' = %t\\n", o.GetType(), o.Validate("test")) default: fmt.Printf(" 未知对象类型: %T\\n", obj) } } // 安全的字符串断言 func safeStringAssertion(value interface{}) (string, error) { if str, ok := value.(string); ok { return str, nil } return "", fmt.Errorf("无法将 %T 类型断言为 string", value) } /* 运行这个程序: go run 03-type-assertions.go 学习要点: 1. 类型断言用于从接口值中提取具体类型 2. 安全断言返回值和布尔标志,不安全断言可能 panic 3. 类型 switch 是处理多种类型的优雅方式 4. 接口可以断言为具体类型或其他接口 5. 类型断言在错误处理、插件系统等场景中很有用 类型断言语法: 1. 不安全断言:value.(Type) - 失败时 panic 2. 安全断言:value, ok := value.(Type) - 返回值和布尔标志 3. 类型 switch:switch value.(type) - 处理多种类型 类型断言的应用场景: 1. 错误处理:检查错误的具体类型 2. 接口功能检查:检查接口是否支持额外方法 3. 插件系统:动态调用不同插件的方法 4. 数据序列化:根据类型选择序列化方式 5. 类型转换:在不同类型间进行转换 最佳实践: 1. 总是使用安全的类型断言 2. 优先使用类型 switch 处理多种类型 3. 提供有意义的错误处理 4. 避免过深的类型断言链 5. 考虑使用接口而不是具体类型断言 性能考虑: 1. 类型断言有运行时开销 2. 在热点代码中谨慎使用 3. 考虑缓存断言结果 4. 优先使用具体类型而不是接口 常见陷阱: 1. 忽略断言的 ok 返回值 2. 对 nil 接口进行断言 3. 不理解接口的动态类型和动态值 4. 过度使用类型断言而不是接口设计 注意事项: 1. nil 接口值的断言总是失败 2. 类型断言只能用于接口类型 3. 断言失败时的零值行为 4. 接口到接口的断言规则 5. 类型断言与反射的区别 */