1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "strconv" 8 ) 9 10 // 1. 结构存在的意义 11 type Cat struct{} 12 13 func (c Cat) say() { fmt.Println("喵喵喵") } 14 15 type Dog struct{} 16 17 func (d Dog) say() { fmt.Println("汪汪汪") } 18 19 func f1() { 20 c1 := Cat{} 21 c1.say() 22 d1 := Dog{} 23 d1.say() 24 // 如果有更多的动物,就会有很多重复的代码 ... 25 } 26 27 // 2. 使用接口 28 // 一个类型可以实现多个接口 Dog => Sayer() 和 Mover() 29 // 一个接口,也可以实现多个类型,如 Dog, Cat 的 say() 30 type Sayer interface { 31 say() 32 } 33 34 func f2() { 35 var x Sayer // 声明一个Sayer类型的变量x 36 c := Cat{} // 实例化一个cat 37 d := Dog{} // 实例化一个dog 38 x = c // 可以把cat实例直接赋值给x 39 x.say() 40 x = d 41 d.say() 42 } 43 44 // 3. 值接收者 和 指针接收者 实现接口的区别 45 type Mover interface { 46 move() 47 } 48 49 func (d *Dog) move() { 50 fmt.Println("狗会跑") 51 } 52 53 func f3() { 54 var x Mover 55 56 // 指针接收者是可以的 57 var jww = &Dog{} 58 x = jww 59 x.move() 60 61 // 会报错 move method has pointer receiver 62 // var hsq = Dog{} 63 // x = hsq 64 // x.move() 65 } 66 67 // 4. 一个接口的方法,不一定需要由一个类型完全实现,可以嵌入其他结构体 68 type WashingMaching interface { 69 wash() 70 dry() 71 } 72 73 type Dryer struct{} 74 75 func (d Dryer) dry() { 76 fmt.Println("甩一甩") 77 } 78 79 type Haier struct { 80 Dryer // 嵌入结构体,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现 81 } 82 83 func (c Haier) wash() { 84 fmt.Println("洗一洗") // 同时有自己的方法 85 } 86 87 func f4() { 88 var x WashingMaching 89 90 var h = Haier{} 91 x = h // 必须一个类型实现了接口的所有方法才可以 92 x.dry() 93 x.wash() 94 95 // d 只有 dry 方法,不能赋值给 x "missing wash method" 96 // d := Dryer{} 97 // x = d 98 // x.dry() 99 } 100 101 // 5. 接口嵌套 102 type Animal interface { 103 Sayer 104 Mover 105 } 106 107 func (c *Cat) move() { // 补上猫的 move 方法 108 fmt.Println("猫会跑") 109 } 110 111 func f5() { 112 var x Animal 113 bsm := &Cat{} 114 x = bsm 115 x.move() 116 x.say() 117 118 } 119 120 // 6. 空接口及应用 动态类型 动态值 121 122 // 空接口作为函数参数 123 func show(a interface{}) { 124 fmt.Printf("type:%T value:%v\n", a, a) 125 } 126 127 func f6() { 128 // 定义一个空接口x 129 var x interface{} 130 131 // 空接口类型的变量可以存储任意类型的变量 132 s := "Hello 沙河" 133 x = s 134 fmt.Printf("type:%T value:%v\n", x, x) // type:string value:Hello 沙河 135 i := 100 136 x = i 137 fmt.Printf("type:%T value:%v\n", x, x) // type:int value:100 138 b := true 139 x = b 140 fmt.Printf("type:%T value:%v\n", x, x) // type:bool value:true 141 142 // 使用空接口实现可以接收任意类型的函数参数 143 show(123) // type:int value:123 144 show("helloworld") // type:string value:helloworld 145 } 146 147 // 7. 接口类型判断 接口类型断言 148 func interfaceType(x interface{}) { 149 switch v := x.(type) { 150 case string: 151 fmt.Printf("x is a string,value is %v\n", v) 152 case int: 153 fmt.Printf("x is a int is %v\n", v) 154 case bool: 155 fmt.Printf("x is a bool is %v\n", v) 156 default: 157 fmt.Println("unsupport type!") 158 } 159 } 160 161 func f7() { 162 var x interface{} 163 x = "cat" 164 165 v, ok := x.(string) 166 if ok { 167 fmt.Println(v, ok) // cat true 168 } 169 170 interfaceType(x) // x is a string,value is cat 171 } 172 173 // 额外,根据函数名执行函数 174 func Call(m map[string]interface{}, name string, params ...interface{}) (result []reflect.Value, err error) { 175 f := reflect.ValueOf(m[name]) 176 if len(params) != f.Type().NumIn() { 177 err = errors.New("The number of params is not adapted.") 178 return 179 } 180 in := make([]reflect.Value, len(params)) 181 for k, param := range params { 182 in[k] = reflect.ValueOf(param) 183 } 184 result = f.Call(in) 185 return 186 } 187 188 func main() { 189 funcs := map[string]interface{}{ 190 "f1": f1, 191 "f2": f2, 192 "f3": f3, 193 "f4": f4, 194 "f5": f5, 195 "f6": f6, 196 "f7": f7, 197 } 198 199 for i := 7; i < 8; i++ { 200 fName := "f" + strconv.Itoa(i) 201 Call(funcs, fName) 202 } 203 }