【原创】go语言学习(十三)struct介绍2

目录:

  • 方法的定义
  • 函数和方法的区别
  • 值类型和指针类型
  • 面向对象和继承
  • 结构体和json序列化

方法的定义

1、和其他语言不一样,Go的方法采⽤用另外一种方式实现。

package main

import "fmt"

type Integer int

func (i Integer) Print() {
	fmt.Println(i)
}

func main() {
	var a Integer
	a = 1000
	a.Print()

	var b int = 200
	a = Integer(b)
	a.Print()
}

// 结果
// 1000
// 200

  

2、Go的方法是在函数前面加上一个接受者,这样编译器器就知道这个方法属于哪个类型了

type A struct {
}
func (a A) Test(s string) {
}

  Test的接受者,因此A这个对象有一个Test方法。

  通过a来访问A的实例例中的成员变量量,也就是struct中的字段

3、可以为当前包内定义的任何类型增加方法

type int Integer //Integer是int的别名
func (a Integer) Test(s string) {
}

  通过a来访问Integer的实例例中的成员变量量,也就是int

  Test的接受者,因此Integer这个对象有一个Test方法

函数和方法的区别

1、函数不属于任何类型,方法属于特定的类型

type People struct {
	Name    string
	Country string
}

// 函数
fun PrintTest(){
    fmt.Printf("name=%s country=%s",People.Name,People.Country)
}

// 方法
func (p People) Print() {
	fmt.Printf("name=%s country=%s\n", p.Name, p.Country)
}

  

 

值类型和指针类型

1、 指针类型作为接受者

type A struct {
}
func (a *A) Test(s string) {
}

  Test的接受者,因此A这个对象有⼀一个Test⽅方法

  通过a来访问A的实例例中的成员变量量,也就是struct中的字段

2、指针类型和值类型作为接受者的区别

// 值类型,copy原理,性能不好
func (p People) Set(name string, country string) {
p.Name = name
p.Country = country

}

// 必须使用指针,否则更改不了原始数据 func (p *People) SetV2(name string, country string) { p.Name = name p.Country = country }

3、什么时候⽤用值类型/指针类型作为接受者?

A. 需要修改接受者中的值的时候
B. 接受者是大对象的时候,副本拷贝代价比较大
C. 一般来说,通常使用指针类型作为接受者

面向对象和继承

1、 匿名结构体与继承

type Animal struct {
    Name string
}

type People struct {
    Sex string
    Age int
    Animal //or *Animal
}

  

2、多重继承与冲突解决

type Mother struct {
    Name string
}

type Father struct {
    Name string
}

type People struct {
    Sex string
    Age int
    *Mother
    *Father
}

  

结构体和json序列化

1、结构体序列列化:结构体转成json数据格式

type People struct {
    Sex string
    Age int
    *Mother
    *Father
}

  

2、结构体反序列列化:json数据格式转成结构体

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	Id   string
	Name string
	Sex  string
}

type Class struct {
	Name     string
	Count    int
	Students []*Student
}

// json用反引号引起来
var rawJson = `{"Name":"101","Count":0,"Students":[{"Id":"0","Name":"stu0","Sex":"man"},{"Id":"1","Name":"stu1","Sex":"man"},{"Id":"2","Name":"stu2","Sex":"man"},{"Id":"3","Name":"stu3","Sex":"man"},{"Id":"4","Name":"stu4","Sex":"man"},{"Id":"5","Name":"stu5","Sex":"man"},{"Id":"6","Name":"stu6","Sex":"man"},{"Id":"7","Name":"stu7","Sex":"man"},{"Id":"8","Name":"stu8","Sex":"man"},{"Id":"9","Name":"stu9","Sex":"man"}]}`

func main() {
	c := &Class{
		Name:  "101",
		Count: 0,
	}

	for i := 0; i < 10; i++ {
		stu := &Student{
			Name: fmt.Sprintf("stu%d", i),
			Sex:  "man",
			Id:   fmt.Sprintf("%d", i),
		}
		c.Students = append(c.Students, stu)
	}

	// json 序列化
	data, err := json.Marshal(c)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}

	fmt.Printf("json:%s\n", string(data))

	// json 反序列化
	fmt.Println("unmarsha1 result is \n\n")
	var c1 *Class = &Class{}
	err = json.Unmarshal([]byte(rawJson), c1)
	if err != nil {
		fmt.Println("unmarhsal failed")
		fmt.Println(err)
		return
	}
	fmt.Printf("c1:%#v\n", c1)

	for _, v := range c1.Students {
		fmt.Printf("stu:%#v\n", v)
	}
}

  

posted @ 2019-11-07 16:36  shuyang  阅读(274)  评论(0编辑  收藏  举报