千家信息网

什么是Golang通脉方法

发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,本篇内容主要讲解"什么是Golang通脉方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"什么是Golang通脉方法"吧!目录方法和接收者指针类型的接收者
千家信息网最后更新 2025年11月07日什么是Golang通脉方法

本篇内容主要讲解"什么是Golang通脉方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"什么是Golang通脉方法"吧!

目录
  • 方法和接收者

    • 指针类型的接收者

    • 值类型的接收者

  • 方法和函数

    • 任意类型添加方法

      • 方法继承

        • 方法重写

          • 结构体和方法补充

            方法和接收者

            Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。

            Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集

            方法只是一个函数,它带有一个特殊的接收器类型,它是在func关键字和方法名之间编写的。接收器可以是struct类型或非struct类型。接收方可以在方法内部访问。

            方法能给用户自定义的类型添加新的行为。它和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。接收者可以是值接收者,也可以是指针接收者。

            在调用方法的时候,值类型既可以调用值接收者的方法,也可以调用指针接收者的方法;指针类型既可以调用指针接收者的方法,也可以调用值接收者的方法。

            也就是说,不管方法的接收者是什么类型,该类型的值和指针都可以调用,不必严格符合接收者的类型。

            方法的定义格式如下:

            func (t Type) methodName(parameter)(return) {  }

            其中

            • t:接收者中的参数变量名在命名时,官方建议使用接收者类型名称首字母的小写,而不是selfthis之类的命名。

            • Type:接收者类型和参数类似,可以是指针类型和非指针类型。

            • methodNameparameterreturn :具体格式与函数定义相同。

            //Person 结构体type Person struct { name string age  int8} //NewPerson 构造函数func NewPerson(name string, age int8) *Person { return &Person{  name: name,  age:  age, }} //Dream Person做梦的方法func (p Person) Dream() { fmt.Printf("%s的梦想是学好Go语言!\n", p.name)} func main() { p1 := NewPerson("张三", 25) p1.Dream()}

            方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。

            可以定义相同的方法名:

            type Rectangle struct { width, height float64}type Circle struct { radius float64}  func (r Rectangle) area() float64 { return r.width * r.height}//该 method 属于 Circle 类型对象中的方法func (c Circle) area() float64 { return c.radius * c.radius * math.Pi}func main() { r1 := Rectangle{12, 2} r2 := Rectangle{9, 4} c1 := Circle{10} c2 := Circle{25} fmt.Println("Area of r1 is: ", r1.area()) fmt.Println("Area of r2 is: ", r2.area()) fmt.Println("Area of c1 is: ", c1.area()) fmt.Println("Area of c2 is: ", c2.area())}

            运行结果:

            Area of r1 is: 24
            Area of r2 is: 36
            Area of c1 is: 314.1592653589793
            Area of c2 is: 1963.4954084936207

            • 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样

            • method里面可以访问接收者的字段

            • 调用method通过.访问,就像struct里面访问字段一样

            指针类型的接收者

            指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。这种方式就十分接近于其他语言中面向对象中的this或者self

            type Rectangle struct { width, height int} func (r *Rectangle) setVal() { r.height = 20} func main() { p := Rectangle{1, 2} s := p p.setVal() fmt.Println(p.height, s.height)}

            结果:

            20 2

            值类型的接收者

            当方法作用于值类型接收者时,Go语言会在代码运行时将接收者的值复制一份。在值类型接收者的方法中可以获取接收者的成员值,但修改操作只是针对副本,无法修改接收者变量本身。

            type Rectangle struct { width, height int} func (r Rectangle) setVal() { r.height = 20} func main() { p := Rectangle{1, 2} s := p p.setVal() fmt.Println(p.height, s.height)  // 2 2}

            什么时候应该使用指针类型接收者

            • 需要修改接收者中的值

            • 接收者是拷贝代价比较大的大对象

            • 保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。

            方法和函数

            已经有了函数,为什么还要使用方法?

            type Employee struct {      name     string    salary   int    currency string} /* displaySalary() method converted to function with Employee as parameter*/func displaySalary(e Employee) {      fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)} func main() {      emp1 := Employee{        name:     "Sam Adolf",        salary:   5000,        currency: "$",    }    displaySalary(emp1)}

            在上面的程序中,displaySalary方法被转换为一个函数,而Employee struct作为参数传递给它。这个程序也产生了相同的输出:Salary of Sam Adolf is $5000.。

            为什么可以用函数来写相同的程序呢?有以下几个原因:

            Go不是一种纯粹面向对象的编程语言,它不支持类。因此,类型的方法是一种实现类似于类的行为的方法。
            相同名称的方法可以在不同的类型上定义,而具有相同名称的函数是不允许的。

            任意类型添加方法

            在Go语言中,接收者的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法。 举个例子,我们基于内置的int类型使用type关键字可以定义新的自定义类型,然后为我们的自定义类型添加方法。

            //MyInt 将int定义为自定义MyInt类型type MyInt int //SayHello 为MyInt添加一个SayHello的方法func (m MyInt) SayHello() { fmt.Println("Hello, 我是一个int。")}func main() { var m1 MyInt m1.SayHello() //Hello, 我是一个int。 m1 = 100 fmt.Printf("%#v  %T\n", m1, m1) //100  main.MyInt}

            注意事项: 非本地类型不能定义方法,也就是说我们不能给别的包的类型定义方法。

            方法继承

            方法是可以继承的,如果匿名字段实现了一个方法,那么包含这个匿名字段的struct也能调用该方法

            type Human struct { name  string age   int phone string}type Student struct { Human  //匿名字段 school string}type Employee struct { Human   //匿名字段 company string} func (h *Human) SayHi() { fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)}func main() { mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} mark.SayHi() sam.SayHi()}

            运行结果:

            Hi, I am Mark you can call me on 222-222-YYYYHi, I am Sam you can call me on 111-888-XXXX

            方法重写

            type Human struct { name  string age   int phone string}type Student struct { Human  //匿名字段 school string}type Employee struct { Human   //匿名字段 company string} //Human定义methodfunc (h *Human) SayHi() { fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)} //Employee的method重写Human的methodfunc (e *Employee) SayHi() { fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,  e.company, e.phone) //Yes you can split into 2 lines here.}func main() { mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} mark.SayHi() sam.SayHi()}

            运行结果:

            Hi, I am Mark you can call me on 222-222-YYYY
            Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX

            • 方法是可以继承和重写的

            • 存在继承关系时,按照就近原则,进行调用

            结构体和方法补充

            因为slicemap这两种数据类型都包含了指向底层数据的指针,因此在需要复制它们时要特别注意:

            type Person struct { name   string age    int8 dreams []string} func (p *Person) SetDreams(dreams []string) { p.dreams = dreams} func main() { p1 := Person{name: "张三", age: 18} data := []string{"吃饭", "睡觉", "打豆豆"} fmt.Printf("%p\n",data)  //0xc00006e360 p1.SetDreams(data)      //传的是 data 的内存地址,此时p.dreams和data指向同一块内存空间 fmt.Printf("%p\n",p1.dreams) //0xc00006e360  // 你真的想要修改 p1.dreams 吗? data[1] = "不睡觉"    //data值的修改会影响person结构体的dream字段 fmt.Println(p1.dreams)  // [吃饭 不睡觉 打豆豆]}

            正确的做法是在方法中使用传入的slice的拷贝进行结构体赋值。

            func (p *Person) SetDreams(dreams []string) { p.dreams = make([]string, len(dreams)) copy(p.dreams, dreams)}

            同样的问题也存在于返回值slicemap的情况,在实际编码过程中一定要注意这个问题。

            到此,相信大家对"什么是Golang通脉方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

            方法 类型 接收者 指针 函数 字段 结构 语言 相同 变量 对象 结果 运行 参数 名称 程序 也就是 也就是说 作用 关键 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全法规的 负责统筹 专科患者数据库 计算机网络技术的发展前沿 九思连强互联网电子科技有限公司 数据库连接类命名 家里电子设备连接访客网络安全吗 信息网络安全绘画人物 临沂智慧养老软件开发专业制作 统计软件开发 兼职 如何查看磁盘存储服务器ip地址 丰县职业技术学校计算机网络技术 肾脏病领域基因数据库 周冬青万方数据库论文 苹果手机为什么要激活服务器 软件开发学生电脑笔记本推荐 农总行软件开发待遇怎么样 湖州软件开发哪家正规 徐州无线网络技术推荐咨询 办公电脑网络安全风险自查 mac创建svn服务器 大话西游2乌鸡国变什么服务器了 做网站服务器怎么样 长沙东塔网络安全学院免费试学 37岁学软件开发 世界根服务器由谁管理 数据库备份在哪里 软件开发与编程学习 linux网站服务器搭建 济南物流软件开发费用多少 奇安信网络安全基础
            0