zoukankan      html  css  js  c++  java
  • go语法-结构体和接口-细节

    结构体和接口对于前端背景的我来说,还是有一些新的知识点,这主要提现在细节上。比如方法和函数不一样。

    方法只有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的内容)

  • 相关阅读:
    如何下载无水印的抖音视频?
    @valid和自定义异常
    Centos7查看外网ip,yum安装的curl无法正常使用
    ElasticSearch安装
    Redis的主从架构+哨兵模式
    Redis的持久化方式
    Nacos 注册中心集群搭建
    kafka安装流程
    WinUI 3学习笔记(1)—— First Desktop App
    .NET 5学习笔记(12)——WinUI 3 Project Reunion 0.5
  • 原文地址:https://www.cnblogs.com/zccst/p/14129105.html
Copyright © 2011-2022 走看看