go方法的定义

 

 

一、 go方法的定义

     Go的方法是在函数前面加一个接受者,这样编译器就知道这个方法属于哪个类型的了。以下是为一个类型定义一个方法的过程

示例:

package main

import (
	"fmt"
)

type Student struct { //定义了一个类型叫 Student。
	Name string
	Age  int
}

//定义了一个值类型为Student的GetName方法
func (stu Student) GetName() string { //为 Student 类型定义了一个方法叫 GetName
	return stu.Name
}
//定义了一个指针类型为Student的 SetName方法
func (stu Student) SetName(name string) { //为 Student 类型定义了一个方法叫 SetName,调用时需要传入一个参数
	stu.Name = name
}

func (stu *Student) Setname(name string) {
	stu.Name = name
}
func main() {
	//定义了一个类型为Student的变量
	//定义一个变量类型为Student,然后并赋值
	var s01 Student
	s01 = Student{
		Name: "s01",
		Age:  18,
	}
	name := s01.GetName()
	fmt.Printf("name=%s\n", name)

	s01.SetName("s02") //这里的s01就是,定义方法func (stu *Student) Setname(name string) 里面的stu,Stu就是s01的拷贝
	name = s01.GetName()
	fmt.Printf("name = %s\n", name)

	//(&s01).Setname("s02") 正规写法,下面的写法是GO帮助我们做了取地址的动作
	s01.Setname("s03")
	name = s01.GetName()
	fmt.Printf("name = %s\n", name)
}

  

*函数和方法的区别,函数不属于任何类型,方法属于特定的类型

*什么时候用值类型或指针类型做为方法的接受者?

    1)需要修改接受者中的值的时候

    2)接受者是大对象的时候,副本拷贝代价比较大

    3)一般来说,通常使用指针类型作为同接受者,就可以了。

 

示例:

package main

import (
	"fmt"
	"time"
)

type User struct {
	s1 [10000000]int64
	s2 [10000000]int64
	s3 [10000000]int64
	s4 [10000000]int64
}
//func (u User) Set() {  换成值类型
func (u *User) Set() {
	for i := 0; i < len(u.s1); i++ {
		u.s1[i] = 1
		u.s2[i] = 1
		u.s3[i] = 1
		u.s4[i] = 1
	}
}

func main() {
	//var u *User = new(User)  //初始化指针
	var u *User = &User{  //初始化指针
	}

    start := time.Now().UnixNano()
	u.Set()
	end := time.Now().UnixNano()

	fmt.Printf("cost:%d ns\n", (end - start)/1000)
	
}

  运行结果,运行速度提升近一倍

bogon:struct_copy jianglinguo$ ./struct_copy 
cost:408596 ns
bogon:struct_copy jianglinguo$ go build
bogon:struct_copy jianglinguo$ ./struct_copy 
cost:181123 ns

  

2、方法的继承

package main

import (
	"fmt"
)

type Animal struct {
	Name string
	Age int
}

func (a * Animal) SetName(name string) {
	a.Name = name
}

func (a *Animal) SetAge(age int) {
	a.Age = age
}

func (a * Animal) PrintHandle() {
	fmt.Printf("a.name = %s a.age = %d\n", a.Name, a.Age)
}

type Bird struct {
	//Animal
	//Animal *Animal  字段如果不指定名字默认使用Animal
	*Animal  //*Animal这个是指针要初始化一下,字段如果不指定名字默认使用Animal
}

func (b *Bird) Fly() {
	fmt.Printf("name %s is fly\n", b.Name)
}

func main() {
	var b *Bird = &Bird{
		Animal: &Animal{}, //初始化Animal
	}
	b.SetName("bird") //bird继承了Animal所以,b就有Animal的方法
	b.SetAge(13) //bird继承了Animal所以,b就有Animal的方法
	b.Fly()   //这个 Fly是bird的方法
}

  JSON序列化

package main

import (
	"fmt"
	"encoding/json"
)

type Animal struct {
	Name string
	Age int
}

func (a * Animal) SetName(name string) {
	a.Name = name
}

func (a *Animal) SetAge(age int) {
	a.Age = age
}

func (a * Animal) PrintHandle() {
	fmt.Printf("a.name = %s a.age = %d\n", a.Name, a.Age)
}

type Bird struct {
	//Animal
	//Animal *Animal  字段如果不指定名字默认使用Animal
	*Animal  //*Animal这个是指针要初始化一下,字段如果不指定名字默认使用Animal
}

type Dog struct {
	*Animal
}

func (b *Bird) Fly() {
	fmt.Printf("name %s is fly\n", b.Name)
}

func main() {
	var b *Bird = &Bird{
		Animal: &Animal{}, //初始化Animal
	}
	b.SetName("bird") //bird继承了Animal类型所以,b就有Animal的方法
	b.SetAge(13) //bird继承了Animal类型所以,b就有Animal的方法
	b.Fly()   //这个 Fly是bird的方法

	data, err := json.Marshal(b)   //josn序列化
	fmt.Printf("marshal result:%s   err:%v\n", string(data), err)

	var c Bird
	err = json.Unmarshal(data, &c)  //json序列化
	fmt.Printf("c:%#v, err:%v\n", c.Animal, err)
}

  

 

posted @ 2019-04-01 18:23  Brin.Guo  阅读(430)  评论(0)    收藏  举报