|
|
@@ -0,0 +1,409 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+func main() {
|
|
|
+ fmt.Println("=== Go 接口、类型断言和类型转换演示 ===\n")
|
|
|
+
|
|
|
+ // 1. 接口基本演示
|
|
|
+ demoInterface()
|
|
|
+
|
|
|
+ // 2. 空接口演示
|
|
|
+ demoEmptyInterface()
|
|
|
+
|
|
|
+ // 3. 类型断言演示
|
|
|
+ demoTypeAssertion()
|
|
|
+
|
|
|
+ // 4. 类型转换演示
|
|
|
+ demoTypeConversion()
|
|
|
+
|
|
|
+ // 5. 综合应用示例
|
|
|
+ demoComprehensive()
|
|
|
+}
|
|
|
+
|
|
|
+// ================================
|
|
|
+// 1. 接口定义和实现
|
|
|
+// ================================
|
|
|
+
|
|
|
+// Writer 接口定义
|
|
|
+type Writer interface {
|
|
|
+ Write([]byte) (int, error)
|
|
|
+}
|
|
|
+
|
|
|
+// Reader 接口定义
|
|
|
+type Reader interface {
|
|
|
+ Read([]byte) (int, error)
|
|
|
+}
|
|
|
+
|
|
|
+// ReadWriter 组合接口
|
|
|
+type ReadWriter interface {
|
|
|
+ Reader
|
|
|
+ Writer
|
|
|
+}
|
|
|
+
|
|
|
+// File 结构体实现接口
|
|
|
+type File struct {
|
|
|
+ name string
|
|
|
+}
|
|
|
+
|
|
|
+// File 实现 Writer 接口
|
|
|
+func (f File) Write(data []byte) (int, error) {
|
|
|
+ fmt.Printf("Writing to %s: %s\n", f.name, string(data))
|
|
|
+ return len(data), nil
|
|
|
+}
|
|
|
+
|
|
|
+// File 实现 Reader 接口
|
|
|
+func (f File) Read(data []byte) (int, error) {
|
|
|
+ content := fmt.Sprintf("Content from %s", f.name)
|
|
|
+ copy(data, []byte(content))
|
|
|
+ fmt.Printf("Reading from %s\n", f.name)
|
|
|
+ return len(content), nil
|
|
|
+}
|
|
|
+
|
|
|
+func demoInterface() {
|
|
|
+ fmt.Println("1. 接口基本演示:")
|
|
|
+ fmt.Println("----------------")
|
|
|
+
|
|
|
+ var w Writer = File{"example.txt"}
|
|
|
+ w.Write([]byte("Hello World"))
|
|
|
+
|
|
|
+ var r Reader = File{"data.txt"}
|
|
|
+ r.Read(make([]byte, 50))
|
|
|
+
|
|
|
+ var rw ReadWriter = File{"readwrite.txt"}
|
|
|
+ rw.Write([]byte("Data to write"))
|
|
|
+ rw.Read(make([]byte, 50))
|
|
|
+
|
|
|
+ fmt.Println()
|
|
|
+}
|
|
|
+
|
|
|
+// ================================
|
|
|
+// 2. 空接口演示
|
|
|
+// ================================
|
|
|
+
|
|
|
+// printAnything 接受任何类型的空接口参数
|
|
|
+func printAnything(v interface{}) {
|
|
|
+ fmt.Printf("值: %v, 类型: %T\n", v, v)
|
|
|
+}
|
|
|
+
|
|
|
+func demoEmptyInterface() {
|
|
|
+ fmt.Println("2. 空接口演示:")
|
|
|
+ fmt.Println("----------------")
|
|
|
+
|
|
|
+ printAnything(42) // int
|
|
|
+ printAnything("hello") // string
|
|
|
+ printAnything([]int{1, 2, 3}) // slice
|
|
|
+ printAnything(3.14) // float64
|
|
|
+ printAnything(true) // bool
|
|
|
+
|
|
|
+ fmt.Println()
|
|
|
+}
|
|
|
+
|
|
|
+// ================================
|
|
|
+// 3. 类型断言演示
|
|
|
+// ================================
|
|
|
+
|
|
|
+// Animal 接口
|
|
|
+type Animal interface {
|
|
|
+ Speak() string
|
|
|
+}
|
|
|
+
|
|
|
+// Dog 实现 Animal 接口
|
|
|
+type Dog struct{ name string }
|
|
|
+
|
|
|
+func (d Dog) Speak() string {
|
|
|
+ return "Woof! My name is " + d.name
|
|
|
+}
|
|
|
+
|
|
|
+// Cat 实现 Animal 接口
|
|
|
+type Cat struct{ name string }
|
|
|
+
|
|
|
+func (c Cat) Speak() string {
|
|
|
+ return "Meow! My name is " + c.name
|
|
|
+}
|
|
|
+
|
|
|
+// checkType 使用类型断言检查接口类型
|
|
|
+func checkType(i interface{}) {
|
|
|
+ switch v := i.(type) {
|
|
|
+ case int:
|
|
|
+ fmt.Printf("整数: %d\n", v)
|
|
|
+ case string:
|
|
|
+ fmt.Printf("字符串: %s\n", v)
|
|
|
+ case bool:
|
|
|
+ fmt.Printf("布尔值: %t\n", v)
|
|
|
+ case Dog:
|
|
|
+ fmt.Printf("狗狗在说话: %s\n", v.Speak())
|
|
|
+ case Cat:
|
|
|
+ fmt.Printf("猫咪在说话: %s\n", v.Speak())
|
|
|
+ default:
|
|
|
+ fmt.Printf("未知类型: %T\n", v)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func demoTypeAssertion() {
|
|
|
+ fmt.Println("3. 类型断言演示:")
|
|
|
+ fmt.Println("----------------")
|
|
|
+
|
|
|
+ // 基本类型断言
|
|
|
+ var i interface{} = "hello world"
|
|
|
+
|
|
|
+ // 安全的方式:检查是否成功
|
|
|
+ if s, ok := i.(string); ok {
|
|
|
+ fmt.Printf("断言成功,是字符串: %s\n", s)
|
|
|
+ } else {
|
|
|
+ fmt.Println("不是字符串")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查其他类型失败的情况
|
|
|
+ if n, ok := i.(int); ok {
|
|
|
+ fmt.Printf("是整数: %d\n", n)
|
|
|
+ } else {
|
|
|
+ fmt.Println("不是整数")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 类型switch演示
|
|
|
+ fmt.Println("\n类型switch演示:")
|
|
|
+ checkType(42)
|
|
|
+ checkType("golang")
|
|
|
+ checkType(true)
|
|
|
+ checkType(Dog{"Buddy"})
|
|
|
+ checkType(Cat{"Kitty"})
|
|
|
+
|
|
|
+ // 接口类型断言
|
|
|
+ fmt.Println("\n接口类型断言:")
|
|
|
+ var a Animal = Dog{"Rex"}
|
|
|
+
|
|
|
+ if dog, ok := a.(Dog); ok {
|
|
|
+ fmt.Println("这是一只狗:", dog.Speak())
|
|
|
+ }
|
|
|
+
|
|
|
+ a = Cat{"Mimi"}
|
|
|
+ if cat, ok := a.(Cat); ok {
|
|
|
+ fmt.Println("这是一只猫:", cat.Speak())
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println()
|
|
|
+}
|
|
|
+
|
|
|
+// ================================
|
|
|
+// 4. 类型转换演示
|
|
|
+// ================================
|
|
|
+
|
|
|
+// 自定义温度类型
|
|
|
+type Celsius float64
|
|
|
+type Fahrenheit float64
|
|
|
+
|
|
|
+// 温度转换函数
|
|
|
+func CToF(c Celsius) Fahrenheit {
|
|
|
+ return Fahrenheit(c*9/5 + 32)
|
|
|
+}
|
|
|
+
|
|
|
+func FToC(f Fahrenheit) Celsius {
|
|
|
+ return Celsius((f - 32) * 5 / 9)
|
|
|
+}
|
|
|
+
|
|
|
+// 为Celsius实现String方法
|
|
|
+func (c Celsius) String() string {
|
|
|
+ return fmt.Sprintf("%.1f°C", c)
|
|
|
+}
|
|
|
+
|
|
|
+func (f Fahrenheit) String() string {
|
|
|
+ return fmt.Sprintf("%.1f°F", f)
|
|
|
+}
|
|
|
+
|
|
|
+func demoTypeConversion() {
|
|
|
+ fmt.Println("4. 类型转换演示:")
|
|
|
+ fmt.Println("----------------")
|
|
|
+
|
|
|
+ // 基本类型转换
|
|
|
+ var integer int = 42
|
|
|
+ var floatNum float64 = float64(integer)
|
|
|
+ var unsigned uint = uint(floatNum)
|
|
|
+
|
|
|
+ fmt.Printf("整数: %d, 浮点数: %.2f, 无符号整数: %d\n",
|
|
|
+ integer, floatNum, unsigned)
|
|
|
+
|
|
|
+ // 字符串和字节切片转换
|
|
|
+ text := "Hello, Go!"
|
|
|
+ bytes := []byte(text)
|
|
|
+ textAgain := string(bytes)
|
|
|
+
|
|
|
+ fmt.Printf("原字符串: %s\n", text)
|
|
|
+ fmt.Printf("字节切片: %v\n", bytes)
|
|
|
+ fmt.Printf("转换回字符串: %s\n", textAgain)
|
|
|
+
|
|
|
+ // 自定义类型转换
|
|
|
+ fmt.Println("\n自定义类型转换(温度):")
|
|
|
+ freezingC := Celsius(0)
|
|
|
+ freezingF := CToF(freezingC)
|
|
|
+ fmt.Printf("冰点: %s = %s\n", freezingC, freezingF)
|
|
|
+
|
|
|
+ boilingF := Fahrenheit(212)
|
|
|
+ boilingC := FToC(boilingF)
|
|
|
+ fmt.Printf("沸点: %s = %s\n", boilingF, boilingC)
|
|
|
+
|
|
|
+ // rune和字符串转换
|
|
|
+ chinese := "你好世界"
|
|
|
+ runes := []rune(chinese)
|
|
|
+ backToString := string(runes)
|
|
|
+ fmt.Printf("\n中文字符串: %s\n", chinese)
|
|
|
+ fmt.Printf("Rune数组: %v\n", runes)
|
|
|
+ fmt.Printf("转换回字符串: %s\n", backToString)
|
|
|
+
|
|
|
+ fmt.Println()
|
|
|
+}
|
|
|
+
|
|
|
+// ================================
|
|
|
+// 5. 综合应用示例
|
|
|
+// ================================
|
|
|
+
|
|
|
+// Processor 数据处理接口
|
|
|
+type Processor interface {
|
|
|
+ Process() interface{}
|
|
|
+ GetType() string
|
|
|
+}
|
|
|
+
|
|
|
+// StringProcessor 字符串处理器
|
|
|
+type StringProcessor struct {
|
|
|
+ data string
|
|
|
+}
|
|
|
+
|
|
|
+func (sp StringProcessor) Process() interface{} {
|
|
|
+ return strings.ToUpper(sp.data)
|
|
|
+}
|
|
|
+
|
|
|
+func (sp StringProcessor) GetType() string {
|
|
|
+ return "string"
|
|
|
+}
|
|
|
+
|
|
|
+// IntProcessor 整数处理器
|
|
|
+type IntProcessor struct {
|
|
|
+ data int
|
|
|
+}
|
|
|
+
|
|
|
+func (ip IntProcessor) Process() interface{} {
|
|
|
+ return ip.data * 2
|
|
|
+}
|
|
|
+
|
|
|
+func (ip IntProcessor) GetType() string {
|
|
|
+ return "int"
|
|
|
+}
|
|
|
+
|
|
|
+// processData 处理不同类型的数据
|
|
|
+func processData(processor Processor) {
|
|
|
+ fmt.Printf("处理 %s 类型数据: ", processor.GetType())
|
|
|
+
|
|
|
+ result := processor.Process()
|
|
|
+
|
|
|
+ // 使用类型断言处理不同类型的结果
|
|
|
+ switch v := result.(type) {
|
|
|
+ case string:
|
|
|
+ fmt.Printf("字符串结果: '%s'\n", v)
|
|
|
+ case int:
|
|
|
+ fmt.Printf("整数结果: %d\n", v)
|
|
|
+ default:
|
|
|
+ fmt.Printf("未知结果类型: %T\n", v)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Config 配置接口
|
|
|
+type Config interface {
|
|
|
+ Validate() error
|
|
|
+ Display()
|
|
|
+}
|
|
|
+
|
|
|
+// DatabaseConfig 数据库配置
|
|
|
+type DatabaseConfig struct {
|
|
|
+ Host string `json:"host"`
|
|
|
+ Port int `json:"port"`
|
|
|
+ Username string `json:"username"`
|
|
|
+}
|
|
|
+
|
|
|
+func (dc DatabaseConfig) Validate() error {
|
|
|
+ if dc.Host == "" {
|
|
|
+ return errors.New("主机名不能为空")
|
|
|
+ }
|
|
|
+ if dc.Port <= 0 || dc.Port > 65535 {
|
|
|
+ return errors.New("端口号必须在1-65535之间")
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (dc DatabaseConfig) Display() {
|
|
|
+ fmt.Printf("数据库配置: Host=%s, Port=%d, Username=%s\n",
|
|
|
+ dc.Host, dc.Port, dc.Username)
|
|
|
+}
|
|
|
+
|
|
|
+// loadConfig 模拟配置加载
|
|
|
+func loadConfig(configData map[string]interface{}) error {
|
|
|
+ fmt.Println("\n加载配置演示:")
|
|
|
+
|
|
|
+ if dbConfig, ok := configData["database"].(map[string]interface{}); ok {
|
|
|
+ // 类型断言确保类型安全
|
|
|
+ host, hostOk := dbConfig["host"].(string)
|
|
|
+ port, portOk := dbConfig["port"].(float64) // JSON数字默认是float64
|
|
|
+ username, userOk := dbConfig["username"].(string)
|
|
|
+
|
|
|
+ if !hostOk || !portOk || !userOk {
|
|
|
+ return errors.New("数据库配置格式错误")
|
|
|
+ }
|
|
|
+
|
|
|
+ config := DatabaseConfig{
|
|
|
+ Host: host,
|
|
|
+ Port: int(port), // 类型转换
|
|
|
+ Username: username,
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := config.Validate(); err != nil {
|
|
|
+ return fmt.Errorf("数据库配置验证失败: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ config.Display()
|
|
|
+ fmt.Println("✅ 数据库配置验证通过")
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func demoComprehensive() {
|
|
|
+ fmt.Println("5. 综合应用示例:")
|
|
|
+ fmt.Println("=================")
|
|
|
+
|
|
|
+ // 数据处理管道演示
|
|
|
+ fmt.Println("数据处理管道:")
|
|
|
+ processData(StringProcessor{"hello golang"})
|
|
|
+ processData(IntProcessor{21})
|
|
|
+
|
|
|
+ // 配置加载演示
|
|
|
+ configData := map[string]interface{}{
|
|
|
+ "database": map[string]interface{}{
|
|
|
+ "host": "localhost",
|
|
|
+ "port": 3306.0, // 注意JSON中的数字是float64
|
|
|
+ "username": "admin",
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := loadConfig(configData); err != nil {
|
|
|
+ fmt.Printf("配置加载错误: %v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 错误配置演示
|
|
|
+ fmt.Println("\n错误配置演示:")
|
|
|
+ badConfig := map[string]interface{}{
|
|
|
+ "database": map[string]interface{}{
|
|
|
+ "host": "", // 空主机名
|
|
|
+ "port": 70000.0, // 无效端口
|
|
|
+ "username": "admin",
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := loadConfig(badConfig); err != nil {
|
|
|
+ fmt.Printf("❌ 配置错误: %v\n", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Println("\n=== 演示结束 ===")
|
|
|
+}
|