3.11 Go Struct structure

3.11 Go Struct structure

Golang support OOP object-oriented programming.

Go of the structure structas a python class.

Go on struct achieve OOP features, only the combination of compositionthis feature.

2. The structure concept

1) The properties of a class of transaction extract a new data type is a structure.

2) to create multiple instances of structures.

3) may be Student structure, it may be Animal, Person structure.

3. The structure features

1) struct is used to define complex data structures

2) struct may comprise a plurality of fields

3) struct method can be defined (note not function, is the golang method)

4) struct value type may be

5) struct type can be nested

6) Go no class, only struct type

7) the structure is defined types can not be transferred to other types of strong

8) may be added to each field struct tag, this tag may be acquired reflection mechanism, such as a scene json serialization and deserialization.

4. The structure is defined

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}
func main() {
    //声明方式
    p1 := Person{"小黑", 18} //有序赋值,并且必须包含所有字段,否则报错
    p2 := Person{Age: 18}  //关键词赋值,未赋值字段有空值
    fmt.Println(p1)
    fmt.Println(p2)
}

Exercise struct

package main

import "fmt"

//声明结构体名称Stu
type Stu struct {
    Name    string //结构体字段
    Age     int    //如未赋值有默认空值
    Address string
    Score   int
}

//结构体可以定义复杂的类型
type Person struct {
    Name  string
    Age   int
    Score [5]float64        //容量为5的数组
    prt   *int              //指针类型
    slice []int             //int类型切片
    map1  map[string]string //map类型字段
    //slice和map默认值是nil,必须make初始化才可使用
}

//结构体是值类型,不同结构体实例之间互不影响
type Monster struct {
    Name string
    Age  int
}

func main() {
    //声明结构体类型变量
    var stu1 Stu
    //结构体可以通过 . 的方式赋值,声明赋值方式一
    stu1.Name = "小黑"
    stu1.Age = 18
    stu1.Address = "沙河"
    stu1.Score = 100
    fmt.Printf("stu1的名字=%v 年纪=%v 住址=%v 分数=%v\n", stu1.Name, stu1.Age, stu1.Address, stu1.Score)

    //声明赋值方式二
    monster1 := Monster{"红孩儿", 18}
    monster2 := Monster{"女妖怪", 999}
    //两个结构体实例,内存地址不一样,确保独立
    fmt.Printf("monster1地址:%p\n", &monster1)
    fmt.Printf("monster2地址:%p\n", &monster2)

    //声明方式三
    //用来分配内存,主要用来分配值类型,比如int、struct。返回指向类型的 指针
    //此时m1是一个指针
    var m1 *Monster = new(Monster)
    //给m1赋值
    (*m1).Name = "孙悟空" //编译器自动识别 同于 m1.Name="孙悟空"
    (*m1).Age = 9999   //同上
    fmt.Println(*m1)   //此时m1是指针变量,加上*取值

    //声明方式四
    m2 := &Monster{
        "猪八戒",
        888,
    }
    fmt.Println(*m2)
    //第三、第四种返回结构体指针,go编译器自动识别,简化程序员心智负担,建议用1、2方法
}

4.1.1. Anonymous structure

No name structure

package main

import "fmt"

func main() {
    //匿名函数
    func() {
        fmt.Println("我是匿名函数")
    }()
    //匿名结构体
    p1 := struct {
        name string
        age  int
    }{
        name: "张三",
        age:  18,
    }
    fmt.Println(p1)
}

4.1.2. AnonymousField

package main

import "fmt"

func main() {
    type student struct {
        string //匿名字段,类型当做字段名
        int
    }
    s1 := student{
        "吴亦凡",
        18,
    }
    fmt.Println(s1.string, s1.int)
}

4.1.3. Nesting structure

Object-oriented: aggregation relationship

A class as a property of another class

package main

import "fmt"

type Book struct {
    bookName string
    price    float64
    author   string
}

type Person struct {
    name string
    age  int
    book Book //继承Book结构体的字段 ,模拟聚合关系
}

func main() {
    //先定义好的book对象
    b1 := Book{"如何找到女朋友", 999.999, "alex金角大王"}
    p1 := Person{"武沛奇", 26, b1} //b1就是Book结构体类型,武沛奇买了一本书
    fmt.Printf("姓名:%s,年纪:%d,书名:%s,价格:%.2f,书的作者:%s\n", p1.name, p1.age, p1.book.bookName, p1.book.price, p1.book.author)

    //声明初始化book对象,一行搞定
    p2 := Person{"萧峰", 25, Book{"如何找到男朋友", 3.58, "超哥著作"}}
    fmt.Printf("姓名:%s,年纪:%d,书名:%s,价格:%.2f,书的作者:%s\n", p2.name, p2.age, p2.book.bookName, p2.book.price, p2.book.author)
}

结构体嵌套练习

Students and shelving,

package main

import "fmt"

type Book struct {
    bookName string
    price    float64
}
type Student struct {
    name  string
    age   int
    books []*Book
}

func main() {
    b1 := Book{"霸道总裁爱上我", 120.22}
    b2 := Book{"斗破苍穹", 12.5}
    b3 := Book{"我和师姐的故事", 15.5}
    //定义书架,默认没有书,可以容纳10本书
    //用Book就是值拷贝,*Book就是放入书的内存地址
    bookSlice := make([]*Book, 0, 10)
    //注意需要传入地址
    bookSlice = append(bookSlice, &b1, &b2, &b3)
    //创建一个学生
    s1 := Student{"小猪沛奇", 3, bookSlice}
    fmt.Printf("姓名:%s,年纪:%d\n", s1.name, s1.age)
    //查看书架上书的信息
    for i := 0; i < len(s1.books); i++ {
        book := s1.books[i]
        fmt.Printf("\t第%d本书,书名:%s,书价格:%.2f\n", i+1, (*book).bookName, book.price)
    }

    //创建图书方式二
    //初始化创建时候,必须对切片分配内存
    s2 := Student{"特斯拉车主alex", 46, make([]*Book, 0, 10)}
    //放入书架的书,放入书的内存地址
    s2.books = append(s2.books, &Book{"斗罗大陆", 55.3}, &Book{"python入门到放弃", 1.28}, &Book{"王思聪与三个网红的一天", 999999.99})
    fmt.Printf("学生名:%s,学习年龄:%d\n", s2.name, s2.age)
    //输入所有s2学生看的书
    for k, v := range s2.books {
        fmt.Printf("\t第%d本书,书名:%s,价格:%.2f\n", k+1, v.bookName, v.price)
    }
}

4.1.4 Object-Oriented: inheritance

A class as a subclass of another class: subclass parent

Inheritance: A second object-oriented features, describe the relationship between two classes for

Subclass, derived class, subClass inherit the parent class (super class, the base class, superClass)

Subclasses can access existing properties and methods of the parent class directly

Subclass can add your own properties and methods

Subclass existing methods can also override the parent class

通过匿名字段的方式,进行嵌套,实现继承关系

package main

import "fmt"

//1.定义父类
type Person struct {
    name string
    age  int
}

//2定义子类,匿名字段,Person即是
type Son struct {
    Person        //模拟继承结构,继承父类的name,age属性
    school string //子类的新增属性
}

func main() {
    //父类
    p1 := Person{"李靖", 999}
    fmt.Println(p1.name, p1.age)
    //子类赋值方式一,子类直接访问父类属性
    var s2 Son
    s2.name = "娜扎"
    s2.age = 666
    s2.school = "神仙学校"
    fmt.Println(s2, s2.name, s2.age, s2.school)
    //创建方式二,简写方式
    s3 := Son{Person{"木吒", 667}, "神仙学校"}
    fmt.Println(s3, s3.name, s3.age, s3.school)

    //创建方式三,基于key-value写
    s4 := Son{Person: Person{name: "金吒", age: 668}, school: "神仙学校"}
    fmt.Println(s4, s4.name, s4.age, s4.school)
}

4.1.5 details of structure

  1. Field structure is continuous in memory
package main

import "fmt"

type Test struct {
    A int32
    B int32
    C int32
    D int32
}

func main() {
    var t Test
    fmt.Printf("a addr:%p\n", &t.A)
    fmt.Printf("b addr:%p\n", &t.B)
    fmt.Printf("c addr:%p\n", &t.C)
    fmt.Printf("d addr:%p\n", &t.D)
}
  1. Structure is defined by the user, can be cast, but it must be exactly the same field, the number, type
  2. Redefine the structure of (re-type), the same effect on the structure别名
  3. Each struct field, a Tag can be written, the tab may be obtained by reflection by the serialization, deserialization
package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    UserName string  `json:"姓名"` //反引号括起来的就是struct tag
    Sex      string  `json:"性别"`
    Score    float32 `json:"成绩"`
    Age      int32   `json:"年纪"`
}

func main() {
    user := &User{
        UserName: "user01",
        Sex:      "男",
        Score:    99.2,
        Age:      18,
    }
    //将user变量序列化为json格式字符串
    data, _ := json.Marshal(user)
    fmt.Printf("json str:%s\n", string(data))
}

4.2 Memory Allocation structure

Look at the code

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    //p1有自己的结构体内存地址,
    var p1 Person
    p1.Age = 10
    p1.Name = "王大锤"

    //定义P2 指针类型,指向p1的内存地址
    var p2 *Person = &p1
    //两种形式一样,go编译器自动识别
    fmt.Println((*p2).Age)
    fmt.Println(p2.Age)
    //修改p2的结构体值,也就是修改了p1的结构体值
    p2.Name = "葫芦娃"
    fmt.Printf("输出结果  p2.Name=%v p1.Name=%v\n", p2.Name, p1.Name)
    fmt.Printf("输出结果(*p2).Name=%v p1.Name=%v\n", (*p2).Name, p1.Name)

    //查看p1和p2的内存地址
    fmt.Printf("p1内存地址%p\n", &p1)
    //p2是指针变量,自己也有一块内存地址,p2的值指向
    fmt.Printf("p2内存地址%p p2的值是%v\n", &p2, p2)
}

4.3. Schematic structure of the memory distribution

Guess you like

Origin www.cnblogs.com/open-yang/p/11256795.html