【原创】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) } }