在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
结构体和接口对于前端背景的我来说,还是有一些新的知识点,这主要提现在细节上。比如方法和函数不一样。 方法只有struct的实例才能调用。而函数就是大家认识的函数,没有任何限制。 9,接口断言 type Shape interface { peri() area() } t1 Triangle = Triangle{3, 4, 5} c1 Circle = Circle{4} var s1 Shape s1 = t1 s1.peri(); s1.area(); // 但不能写s1.a, s1.b, s1.c
var s2 Shape s2 = c1 s2.peri(); s2.area(); // 但不能写s2.r
也可以写一个方法 func testShape(s Shape) {} testShape(t1) testShape(c1) testShape(s1)
instance, ok := 接口对象.(实际类型) func getType (s Shape) { if ins, ok := s.(Triangle) ; ok { fmt.Println(三角形的三边是", ins.a, ins.b, ins.c) } else if ins, ok := s.(Circle) ; ok { fmt.Println(原型的半价是", ins.r) } } 补充1:可以使用指针。 补充2:使用switch方法
8,接口嵌套 接口C 继承 接口A 和 接口B,结构体实现A和B的方法和接口C的方法。 var cat Cat = Cat{} var a1 A = cat var b1 B = cat var c1 C = cat 如果Cat想实现C,必须实现A和B
7,空接口 type A interface {} type Cat struct { color string } type Person { name string age int} var a1 A = Cat{"花猫"} var a2 A = Person{"往", 30} var a3 A = "haha" var a4 A = 100
func test1(a A) {} //可以接受任意类型的参数 func test2(a interface {}) {} //可以接受任意类型的参数
map1 := make(map[string]interface{}) map1["name"] = "李小花" map1["age"] = 30
slice1 := make([]interface{}, 0, 10) slice1 = append(slice1, a1, a2, a3, a4, 100, "abc")
6,接口 意义:解耦合。语言设计者说:接口设计具体突破性 go中接口是一组方法签名。当某个类型为实现了接口中所有方法,它被称为实现接口。 go中接口和类型的实现关系是非侵入式的,其他语言是显示定义 Class Mouse implements USB {} 多态比继承还重要。 动物Animal - Cat(color)和Dog(lookDoor()) 对于狗的实例,既可以作为狗,也可以作为动物。 当作为动物实例时(接口的实例),不能访问狗的方法
用法: 1)一个函数如果接受接口类型作为参数,实际上可以传入任意实现类型对象作为参数。 Animal是接口,则可以传入Cat或Dog,则 var a Animal a = cat //cat := Cat{} Cat的实例,则a可以调用Cat的方法。同理如果是a = dog,则可以调用Dog的方法。
2)定义一个类型为接口乐信,实际上可以赋值为任意实现类的对象。 var arr[3] USB arr[0] = m1;//鼠标实例 m1 := Mouse{"罗技小红"} arr[1] = f1;//u盘实例 f1 := FlashDisk{"闪迪64G"}
鸭子类型:
1)当需要接口类型的对象时,可以使用任意实现类对象代替。 2)接口对象不能访问实现类中的属性。
5,继承中的方法 子类自定义新方法 子类覆盖父类方法
4,方法 用结构体模拟面向对象变成。涉及概念:匿名字段(把结构体作为父结构体的字段),变量提升,方法。 模拟继承性:用匿名字段 用 type Student { Book } 。这样可以直接访问父类的字段和方法。 is a关系 模拟聚合关系:用 type Student { book * Book } 是has a,访问的时候子类无法直接访问父类,而是要通过book来访问。has a关系。
func (w Worker) funcName() () {} w是Worker的实例,而且是值传递。
func (p *Worker) printInfo () {} func (p *Cat) printInfo() {} 方法名不一样,但是各调各的。 为什么要设计方法? 不是纯面向对象。方法是实现类行为的方法,某一类别有的行为功能,需要接受指定的接收者调用 方法名可以相同,只要接收者不同就可以。
3,结构体嵌套 type Person struct { name string age int address Address } 这才是灵魂所在。 s2 := Student {name:"", age:18, book:Book{bookName:"", price: 89.7}} 结构体嵌套需要传递指针。 type Student struct { name string age int book *Book } 不再是值复制,而是地址传递。这才是我们需要的。
2,结构体的匿名字段 匿名函数 匿名结构体 s2 := struct { name string age int } { name: "李四" age: 19 } s2.name, s2.age也能正常访问。 由于定义结构体就是要复用,而匿名结构体不能复用,所以意义不大,不常用,知道就行了。
type Worker struct { name string age int } w1 := Worker{name:"小王", age: 30} type Worker struct { string int } w2 := Worker{"小王", 30} // 这样也可以 默认把类型当做名字了。 但匿名字段类型不能重复,即不能有两个字符串类型。否则会冲突。
还有一个用法:把另一个结构体当做匿名字段。
1,结构体的指针 var pp1 *Person p1:=Person{"","", "",} pp1 = &p1; 修改 new方式创建的就是指针。 pp3 := new(int) // 打印pp3和*pp3(pp3的内容)
|
请发表评论