尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

GO_面向对象_方法

GO_面向对象_方法
📅 发布时间:2026/7/14 20:37:36

一、Go 方法核心概念

1. 方法本质

方法本质是函数,但必须和特定类型绑定(区别于普通函数),是 Go 实现面向对象封装的核心手段。

2. 函数 vs 方法 语法对比

go

// 1. 普通函数(无类型绑定) func 函数名(参数) 返回值 {} // 2. 匿名函数 func() {} // 3. 方法(绑定指定类型,必须有接收者) func (接收者变量 绑定类型) 方法名(参数) 返回值 {}
  • 接收者:相当于方法的第一个参数,是绑定类型的实例
  • 只有绑定了类型的函数,才能叫方法

3. 方法的意义:实现封装

普通函数没有 "归属",方法可以给类型绑定专属函数,就像机器的按钮,隐藏内部实现,对外提供操作接口。


二、方法基础使用

1. 给自定义类型绑定方法

go

package main import "fmt" // 自定义类型 type long int // 普通函数:面向过程 func Add01(a, b long) long { return a + b } // 方法:给long类型绑定,面向对象 // tmp:接收者,相当于参数 func (tmp long) Add02(other long) long { return tmp + other } func main() { // 调用普通函数 res1 := Add01(1, 1) fmt.Println("函数调用:", res1) // 调用方法:变量名.方法名() var a long = 2 res2 := a.Add02(3) fmt.Println("方法调用:", res2) }

核心:面向对象只是换了一种调用方式,本质还是函数。

2. 给结构体类型绑定方法(最常用)

结构体是 Go 中最常用的绑定类型,可实现属性 + 方法的封装:

go

type Person struct { name string sex byte age int } // 绑定打印方法 func (tmp Person) PrintInfo() { fmt.Println("成员信息:", tmp) } // 绑定赋值方法 func (p *Person) SetInfo(n string, s byte, a int) { p.name = n p.sex = s p.age = a } func main() { // 初始化结构体 p := Person{"mike", 'm', 18} p.PrintInfo() // 调用方法 // 指针接收者方法调用 var p2 Person (&p2).SetInfo("yoyo", 'f', 22) p2.PrintInfo() }

三、方法使用规则

1. 接收者类型限制

  1. 接口类型不能作为接收者
  2. 接收者的基础类型本身不能是指针

go

// 错误写法:类型本身是指针,不能做接收者 type pointer *int func (tmp pointer) test() {} // 正确写法:接收者是指针类型(推荐) type long int func (tmp *long) test02() {}

2. 不支持重载,支持同名方法

Go不支持函数重载,但接收者类型不同,同名方法不算重载,是独立方法:

go

type long int type char string // 两个test方法,接收者不同,相互独立 func (tmp long) test() {} func (tmp char) test() {}

四、值接收者 vs 指针接收者(核心重点)

1. 本质区别:值传递 vs 指针传递

类型传递方式效果使用场景
值接收者值拷贝方法内修改,不影响原变量只读操作、小型结构体
指针接收者引用传递方法内修改,直接修改原变量修改成员、大型结构体、提升效率

2. 代码示例

go

type Person struct { name string age int } // 值接收者:值传递,拷贝副本 func (p Person) SetInfoValue(n string, a int) { p.name = n p.age = a } // 指针接收者:引用传递,操作原变量 func (p *Person) SetInfoPointer(n string, a int) { p.name = n p.age = a } func main() { s1 := Person{"go", 22} // 值接收者:不修改原变量 s1.SetInfoValue("mike", 18) fmt.Println(s1) // 输出:{go 22} // 指针接收者:修改原变量 (&s1).SetInfoPointer("mike", 18) fmt.Println(s1) // 输出:{mike 18} }

五、方法集(自动类型转换)

Go 编译器会自动转换接收者类型,无需严格遵守方法集约束:

  1. 指针类型变量,可以调用值接收者 + 指针接收者方法
  2. 普通类型变量,可以调用值接收者 + 指针接收者方法

go

type Person struct { name string } func (p Person) SetInfoValue() {} // 值接收者 func (p *Person) SetInfoPointer() {} // 指针接收者 func main() { // 指针变量:调用两种方法 p1 := &Person{"mike"} p1.SetInfoValue() p1.SetInfoPointer() // 普通变量:调用两种方法 p2 := Person{"mike"} p2.SetInfoValue() p2.SetInfoPointer() // 编译器自动转换为 (&p2).SetInfoPointer() }

六、方法的继承与重写

1. 方法继承:通过匿名字段实现

结构体嵌套匿名结构体,自动继承匿名结构体的所有成员和方法:

go

// 父结构体 type Person struct { name string age int } // 父结构体方法 func (tmp *Person) PrintInfo() { fmt.Printf("姓名:%s,年龄:%d\n", tmp.name, tmp.age) } // 子结构体:嵌套Person(匿名字段),实现继承 type Student struct { Person // 匿名字段 id int addr string } func main() { s := Student{Person{"mike", 18}, 666, "北京"} s.PrintInfo() // 直接调用继承的方法 }

2. 方法重写:就近原则

子结构体定义和父结构体同名的方法,就是方法重写:

  • 调用时:优先调用自身方法(就近原则)
  • 强制调用父类方法:子变量.父结构体.方法()

go

// 子结构体重写方法 func (tmp *Student) PrintInfo() { fmt.Println("学生信息:", tmp) } func main() { s := Student{Person{"mike", 18}, 666, "北京"} // 就近原则:调用子结构体方法 s.PrintInfo() // 显式调用父结构体方法 s.Person.PrintInfo() }

七、方法值 & 方法表达式

1. 方法值

将方法赋值给变量,隐藏接收者,直接调用变量即可:

go

func main() { p := Person{"mike", 18} // 传统调用 p.SetInfoPointer() // 方法值:绑定接收者,直接调用 pFunc := p.SetInfoPointer pFunc() // 等价于 p.SetInfoPointer() vFunc := p.SetInfoValue vFunc() }

2. 方法表达式

显式传递接收者,格式:(类型).方法名:

go

func main() { p := Person{"mike", 18} // 指针接收者方法表达式 f1 := (*Person).SetInfoPointer f1(&p) // 显式传接收者 // 值接收者方法表达式 f2 := (Person).SetInfoValue f2(p) }

八、核心总结

  1. 方法 = 绑定类型的函数,是 Go 封装的核心,接收者是方法第一个参数
  2. 值接收者:拷贝副本,不修改原变量;指针接收者:引用传递,修改原变量
  3. 编译器自动转换接收者类型,方法集无严格调用限制
  4. 匿名字段实现方法继承,同名方法实现方法重写(就近原则)
  5. 方法值 / 表达式:简化方法调用,灵活使用

相关新闻

  • 2026年南宁茅台回收门店推荐排行榜TOP5 - 官方资讯
  • 贵阳制造企业100人春季团建:5万元预算与雨天预案
  • 【Bug已解决】openclaw regex timeout / RegExp execution exceeded — OpenClaw 正则表达式超时解决方案

最新新闻

  • 云市场行业模板如何缩短POC周期:客户成功团队的试点场景包打法
  • Poetry:现代Python工程化依赖管理的核心实践
  • GPU微调实战指南:15个云平台成本、性能与交付对比
  • 欧米茄中国官方售后服务中心|官方电话及详细维修地址权威信息声明(2026年7月更新) - 欧米茄官方服务中心
  • 西门子1200 PLC直连的Metro风上位机框架,含预置通信模块与可复用UI库
  • 数据科学自学生存地图:10个高ROI实战资源精选

日新闻

  • AWS SSM安全运维实践:零公网暴露的合规远程开发方案
  • Tableau 2024.1 图表选择指南:5种业务场景与最佳图表类型匹配
  • dsPIC33FJ与CMT-8540S-SMT在嵌入式音频处理中的高效应用

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号