• Go语言中的方法和函数


    在C#或者Java里面我们都知道,一个Class是要包含成员变量和方法的,对于GO语言的Struct也一样,我们也可以给Struct定义一系列方法。

    一、怎么定义一个方法?

    Go的方法是在函数前面加上一个接收者,这样编译器就知道这个方法属于哪个类型了。例如:

    package demo1
    
    import (
       "fmt"
    )
    
    type Student struct {
       Name string
       Age int
       Class string
    }
    
    func (stu Student) GetUserInfo(student Student)  {
       fmt.Printf("学生姓名:%v 年龄: %v 班级:%v ",student.Name,student.Age,student.Class)
    }

    上面的代码就是定义了一个Student的结构体,然后针对这个结构体,创建了三个方法。我们可以通过【实例名.方法名】的方式来访问这个结构体内的方法。

    package main
    
    import "Function/demo1"
    
    func main(){
       student:=demo1.Student{
          Name:"XiaoMing",
          Age:20,
          Class:"3-2",
       }
    
       student.GetUserInfo(student)
    }

    二、接收者的类型问题

    上面的GetUserInfo的接收者是一个Student类型,这里就会出现一个问题,如果我是设定类的操作,那么不会改变对应实例的值,它只是一个拷贝。下面的例子将说明这个问题,下面这个Set方法接收者是Student

    type Student struct {
       Name string
       Age int
       Class string
    }
    
    func (stu Student) SetStudentName(name string)  {
       stu.Name = name
    }

    main函数中使用这个类

    func main(){
       student:=demo2.Student{
          Name:"XiaoMing",
          Age:20,
          Class:"3-2",
       }
    
       student.SetStudentName("LiLie")
    
       fmt.Printf("Name: %v",student.Name )
    }

    结果:

    Name: XiaoMing

    可以看到,这里并没把Name进行修改。

    如果我们使用Student指针类型作为接收者,则会修改这个值。例子如下:

    func (stu *Student) SetStudentName(name string)  {
       stu.Name = name //这里为什么能stu直接.出Name,是Go的语法糖相当于 (*stu).Name
    }

    再次运营结果为:

    Name: LiLie

    三、何时使用值类型接收者,何时使用指针类型接收者。

    粗暴的结论:如果你不知道怎么选择,那就使用指针。但有时候,使用值接收者会更合理,尤其是效率考虑,比如:不需要修改的小 struct、基础数据类型。以下是一些有用的指导方针:

    - 如果接收者是 map、func 或 chan,不用使用指针。如果是 slice,并且方法不会 reslice 或 从分配 slice,不要使用指针;

    - 如果方法需要修改接收者,必须使用指针; - 如果接收者是包含了 sync.Mutex 或类似的同步字段的结构体(struct),接收者必须使用指针,避免拷贝;

    - 如果接收者是一个大的结构体或数组,使用指针会更高效。但多大是大?如果所有元素(struct 的字段或数组元素)作为方法的参数传递认为太大,那么作为接收者也是太大。(粗暴一些,所有元素内存超过指针大小,可以考虑使用指针);

    - 如果接收者是结构体、数组或 slice,同时,它们的元素是指针,且指向的数据要改变,那么使用指针接收者会更合理;(有点绕,那就总原则:用指针没错);

    - 如果接收者是小的数组,或小的没有可变字段或指针的结构体,或者结构体字段只是简单的基础类型,值接收者会更合理;值接收者能减少垃圾回收的压力,一般会优先分配在栈上(记住是一般,因为有可能逃逸);但除非有性能测试验证,否则别因为可以介绍垃圾回收压力,就选择值接收者;

    最后再强调一下,如果你拿不定主意,那就用指针接收者。

  • 相关阅读:
    入门OJ 4187【周末舞会】
    入门OJ 1532【排队取款】
    洛谷 P3029 [USACO11NOV]【牛的阵容Cow Lineup】
    洛谷 P1638【逛画展】
    入门OJ 1256【排队】
    PKU 1945【Power Hungry Cows】
    RocketMQ重试机制和消息
    Java操作RocketMQ
    RocketMQ概述
    重定向机制
  • 原文地址:https://www.cnblogs.com/dcz2015/p/10782675.html
Copyright © 2020-2023  润新知