0%

Go结构体

Go 面向对象:

  • 结构体
  • 继承
  • 接口

    struct

    结构体声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    package main

    import "fmt"

    type person struct {
    name string
    age int
    }

    func (p *person) setName(name string) {
    p.name = name
    }

    func (p *person) setAge(age int) {
    p.age = age
    }

    func (p person) getName() string {
    return p.name
    }

    // 不用指针为值传递
    func foo(p person) {
    p.setAge(23)
    }

    func main() {
    p := person{"wxy", 21}
    fmt.Printf("%v\n", p)
    fmt.Println(p.getName())
    foo(p)
    fmt.Printf("%v\n", p)
    }

    注意事项

  • 首字母大写为公有,小写为私有(同一个包)。(函数,变量,常量同理
  • 函数传参为值传递,是拷贝的副本,可以使用指针 (直接赋值也是副本)
  • 结构体方法使用 (p Person)(p *person) 绑定 (set方法只用指针)
  • 结构体变量可以直接使用 ==!= 比较
  • &Person{}new(Person) 等价,底层仍会调用 new

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package main

import "fmt"

type Human struct {
name string
sex string
}

func (this *Human) Eat() {
fmt.Println("Human.Eat()...")
}

func (this *Human) Walk() {
fmt.Println("Human.Walk()...")
}

//=================

type SuperMan struct {
Human //SuperMan类继承了Human类的方法

level int
}

//重定义父类的方法Eat()
func (this *SuperMan) Eat() {
fmt.Println("SuperMan.Eat()...")
}

//子类的新方法
func (this *SuperMan) Fly() {
fmt.Println("SuperMan.Fly()...")
}

func (this *SuperMan) Print() {
fmt.Println("name = ", this.name)
fmt.Println("sex = ", this.sex)
fmt.Println("level = ", this.level)
}

func main() {
h := Human{"zhang3", "female"}

h.Eat()
h.Walk()

//定义一个子类对象
//s := SuperMan{Human{"li4", "female"}, 88}
var s SuperMan
s.name = "li4"
s.sex = "male"
s.level = 88

s.Walk() //父类的方法
s.Eat() //子类的方法
s.Fly() //子类的方法

s.Print()
}

interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package main

import "fmt"

//本质是一个指针
type AnimalIF interface {
Sleep()
GetColor() string //获取动物的颜色
GetType() string //获取动物的种类
}

//具体的类
type Cat struct {
color string //猫的颜色
}

func (this *Cat) Sleep() {
fmt.Println("Cat is Sleep")
}

func (this *Cat) GetColor() string {
return this.color
}

func (this *Cat) GetType() string {
return "Cat"
}

//具体的类
type Dog struct {
color string
}

func (this *Dog) Sleep() {
fmt.Println("Dog is Sleep")
}

func (this *Dog) GetColor() string {
return this.color
}

func (this *Dog) GetType() string {
return "Dog"
}

func showAnimal(animal AnimalIF) {
animal.Sleep() //多态
fmt.Println("color = ", animal.GetColor())
fmt.Println("kind = ", animal.GetType())
}

func main() {

var animal AnimalIF //接口的数据类型, 父类指针
animal = &Cat{"Green"}

animal.Sleep() //调用的就是Cat的Sleep()方法 , 多态的现象

animal = &Dog{"Yellow"}

animal.Sleep() // 调用Dog的Sleep方法,多态的现象

cat := Cat{"Green"}
dog := Dog{"Yellow"}

showAnimal(&cat)
showAnimal(&dog)
}

注意事项

  • 结构的本质是一个指针
  • 只要实现了某接口的所有方法,就可以向上转型
  • 空interface( interface{} )没有任何方法,因此所有类型都实现了空interface
  • 使用类型断言来判断并转换数据类型,例如:value, ok := arg.(string)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    package main

    import "fmt"

    //interface{}是万能数据类型
    func myFunc(arg interface{}) {
    fmt.Println("myFunc is called...")
    fmt.Println(arg)

    //interface{} 改如何区分 此时引用的底层数据类型到底是什么?

    //给 interface{} 提供 “类型断言” 的机制
    value, ok := arg.(string)
    if !ok {
    fmt.Println("arg is not string type")
    } else {
    fmt.Println("arg is string type, value = ", value)

    fmt.Printf("value type is %T\n", value)
    }
    }

    type Book struct {
    auth string
    }

    func main() {
    book := Book{"Golang"}

    myFunc(book)
    myFunc(100)
    myFunc("abc")
    myFunc(3.14)
    }