go语言方法集为类型添加方法示例解析
怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《go语言方法集为类型添加方法示例解析》,涉及到方法、go方法集、类型添加,有需要的可以收藏一下
1概述
在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法(method)。本质上,一个方法则是一个和特殊类型关联的函数。
一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这些事情。
在Go语言中,可以给任意自定义类型(包括内置类型,但不包括指针类型)添加相应的方法。
⽅法总是绑定对象实例,并隐式将实例作为第⼀实参 (receiver),方法的语法如下:
func (receiver ReceiverType) funcName (parameters) (results)
- 参数 receiver 可任意命名。如⽅法中未曾使⽤,可省略参数名。
- 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接⼝或指针。
- 不支持重载方法,也就是说,不能定义名字相同但是不同参数的方法。
2为类型添加方法
2.1基础类型作为接收者
type MyInt int//自定义类型,给int改名为MyInt
//在函数定义时,在其名字之前放上一个变量,即是一个方法
func (a MyInt) Add(b MyInt) MyInt {//面向对象
return a + b
}
//传统方式的定义
func Add(a, b MyInt) MyInt {//面向过程
return a + b
}
func main() {
var a MyInt=1 // a := MyInt(1) 等价
var b MyInt=1
//调用func (aMyInt) Add(bMyInt)
fmt.Println("a.Add(b)=",a.Add(b))//a.Add(b)=2
//调用func Add(a,bMyInt)
fmt.Println("Add(a,b)=",Add(a,b))//Add(a,b)=2
}
通过上面的例子可以看出,面向对象只是换了一种语法形式来表达。方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数。
注意:虽然方法的名字一模一样,但是如果接收者不一样,那么方法就不一样。
2.2结构体作为接收者
方法里面可以访问接收者的字段,调用方法通过点(. )访问,就像struct里面访问字段一样:
package main
import "fmt"
func main(){
jeff:=user{1,"jeff",18,"上海"}
fmt.Println(jeff.Add(10))
}
// 相当于定义user类
type user struct {
id int
name string
age int
addr string
}
// 添加Add方法,接收参数num
func (p user) Add(num int)int{
fmt.Println(p.age)
return p.age+num
}
3值语义和引用语义
package main
import "fmt"
func main() {
//指针作为接收者,引用语义
jeff := Person{"jeff","男",18}//初始化
fmt.Println("函数调用前=",jeff)//函数调用前= {jeff 男 18}
(&jeff).Add() // 生效,(&jeff)拿到jeff的地址(指针)
//jeff.Add() // 修改不生效
fmt.Println("函数调用后=",jeff)//函数调用后= {aaa 女 22}
fmt.Println("==========================")
chary := Person{"chary","女",18}//初始化
//值作为接收者,值语义
fmt.Println("函数调用前=",chary)//函数调用前= {chary 女 18}
chary.Add2() //不生效
//(&chary).Add()
fmt.Println("函数调用后=",chary)//函数调用后= {chary 女 18}
}
type Person struct {
name string
sex string
age int
}
//指针作为接收者,引用语义
func (p *Person) Add(){
//给成员赋值
(*p).name = "aaa"
p.sex = "女"
p.age = 22
}
//值作为接收者,值语义
func (p Person) Add2(){
//给成员赋值
p.name = "bbb"
p.sex = "男"
p.age = 22
}
4方法集
类型的方法集是指可以被该类型的值调用的所有方法的集合。
用实例实例 value 和 pointer 调用方法(含匿名字段)不受⽅法集约束,编译器编总是查找全部方法,并自动转换 receiver 实参。
4.1类型 *T 方法集
一个指向自定义类型的值的指针,它的方法集由该类型定义的所有方法组成,无论这些方法接受的是一个值还是一个指针。
如果在指针上调用一个接受值的方法,Go语言会聪明地将该指针解引用,并将指针所指的底层值作为方法的接收者。
类型 *T ⽅法集包含全部 receiver T + *T ⽅法:
type Person struct{
name string
sex byte
age int
}
//指针作为接收者,引用语义
func (p *Person) SetInfoPointer(){
(*p).name="yoyo"
p.sex='f'
p.age=22
}
//值作为接收者,值语义
func (p Person) SetInfoValue(){
p.name="xxx"
p.sex='m'
p.age=33
}
func main() {
//p为指针类型
var p*Person = &Person{"mike",'m',18}
p.SetInfoPointer() //func (p)SetInfoPointer()
p.SetInfoValue() //func (*p)SetInfoValue()
(*p).SetInfoValue() //func (*p)SetInfoValue()
}
4.2类型 T 方法集
一个自定义类型值的方法集则由为该类型定义的接收者类型为值类型的方法组成,但是不包含那些接收者类型为指针的方法。
但这种限制通常并不像这里所说的那样,因为如果我们只有一个值,仍然可以调用一个接收者为指针类型的方法,这可以借助于Go语言传值的地址能力实现。
type Person struct{
name string
sex byte
age int
}
//指针作为接收者,引用语义
func (p *Person) SetInfoPointer(){
(*p).name="yoyo"
p.sex='f'
p.age=22
}
//值作为接收者,值语义
func (p Person)SetInfoValue(){
p.name="xxx"
p.sex='m'
p.age=33
}
func main() {
//p为普通值类型
var p Person = Person{"mike",'m',18}
(&p).SetInfoPointer() //func(&p)SetInfoPointer()
p.SetInfoPointer() //func(&p)SetInfoPointer()
p.SetInfoValue() //func(p)SetInfoValue()
(&p).SetInfoValue() //func(*&p)SetInfoValue()
}
5匿名字段
5.1方法的继承
如果匿名字段实现了一个方法,那么包含这个匿名字段的struct也能调用该方法。
type Person struct {
name string
sex byte
age int
}
//Person定义了方法
func (p *Person) PrintInfo() {
fmt.Printf("%s,%c,%d\n",p.name,p.sex,p.age)
}
type Student struct {
Person//匿名字段,那么Student包含了Person的所有字段
id int
addr string
}
func main() {
p := Person{"mike",'m',18}
p.PrintInfo()
s := Student{Person{"yoyo",'f',20},2,"sz"}
s.PrintInfo()
}
5.2方法的重写
type Person struct {
name string
sex byte
age int
}
//Person定义了方法
func (p *Person) PrintInfo() {
fmt.Printf("Person:%s,%c,%d\n",p.name,p.sex,p.age)
}
type Student struct {
Person//匿名字段,那么Student包含了Person的所有字段
id int
addr string
}
//Student定义了方法
func (s *Student) PrintInfo() {
fmt.Printf("Student:%s,%c,%d\n",s.name,s.sex,s.age)
}
func main() {
p:=Person{"mike",'m',18}
p.PrintInfo() //Person:mike,m,18
s:=Student{Person{"yoyo",'f',20},2,"sz"}
s.PrintInfo() //Student:yoyo,f,20
s.Person.PrintInfo() //Person:yoyo,f,20
}
6方法值和方法表达式
类似于我们可以对函数进行赋值和传递一样,方法也可以进行赋值和传递。
根据调用者不同,方法分为两种表现形式:方法值和方法表达式。两者都可像普通函数那样赋值和传参,区别在于方法值绑定实例,⽽方法表达式则须显式传参。
6.1方法值
type Person struct{
name string
sex byte
age int
}
func (p *Person) PrintInfoPointer() {
fmt.Printf("%p,%v\n",p,p)
}
func (p Person) PrintInfoValue(){
fmt.Printf("%p,%v\n",&p,p)
}
func main() {
p:=Person{"mike",'m',18}
p.PrintInfoPointer() //0xc0420023e0,&{mike 109 18}
pFunc1:=p.PrintInfoPointer //方法值,隐式传递 receiver
pFunc1() //0xc0420023e0,&{mike 109 18}
pFunc2:=p.PrintInfoValue
pFunc2() //0xc042048420,{mike 109 18}
}
6.2方法表达式
type Person struct {
name string
sex byte
age int
}
func (p *Person) PrintInfoPointer() {
fmt.Printf("%p,%v\n",p,p)
}
func (p Person) PrintInfoValue() {
fmt.Printf("%p,%v\n",&p,p)
}
func main() {
p:=Person{"mike",'m',18}
p.PrintInfoPointer()//0xc0420023e0,&{mike 109 18}
//方法表达式,须显式传参
//func pFunc1 (p *Person))
pFunc1:=(*Person).PrintInfoPointer
pFunc1(&p) //0xc0420023e0,&{mike 109 18}
pFunc2:=Person.PrintInfoValue
pFunc2(p) //0xc042002460,{mike 109 18}
}
文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《go语言方法集为类型添加方法示例解析》文章吧,也可关注golang学习网公众号了解相关技术文章。
goGin安装及初始化操作示例
- 上一篇
- goGin安装及初始化操作示例
- 下一篇
- Go interface 接口的最佳实践经验分享
-
- Golang · Go教程 | 7分钟前 |
- GolangCI/CD测试流程实现详解
- 347浏览 收藏
-
- Golang · Go教程 | 12分钟前 |
- Golang模块冲突解决全攻略
- 200浏览 收藏
-
- Golang · Go教程 | 23分钟前 |
- Go语言处理JSON浮点数编码技巧
- 391浏览 收藏
-
- Golang · Go教程 | 42分钟前 |
- Golangselect多路复用实战教程详解
- 307浏览 收藏
-
- Golang · Go教程 | 53分钟前 |
- MGO存储嵌套结构体方法全解析
- 119浏览 收藏
-
- Golang · Go教程 | 9小时前 | 格式化输出 printf fmt库 格式化动词 Stringer接口
- Golangfmt库用法与格式化技巧解析
- 140浏览 收藏
-
- Golang · Go教程 | 9小时前 |
- Golang配置Protobuf安装教程
- 147浏览 收藏
-
- Golang · Go教程 | 9小时前 |
- Golang中介者模式实现与通信解耦技巧
- 378浏览 收藏
-
- Golang · Go教程 | 9小时前 |
- Golang多协程通信技巧分享
- 255浏览 收藏
-
- Golang · Go教程 | 9小时前 |
- Golang如何判断变量类型?
- 393浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3167次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3380次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3409次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4513次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3789次使用
-
- Go方法接收者值接收者与指针接收者详解
- 2022-12-22 438浏览
-
- 基于GORM实现CreateOrUpdate方法详解
- 2023-01-07 353浏览
-
- Go语言中常用的基础方法总结
- 2022-12-22 453浏览
-
- go语言中函数与方法介绍
- 2023-01-07 297浏览
-
- Go读写锁操作方法示例详解
- 2023-01-07 183浏览

