go语言基础-----07-----方法

2023-11-02

1 方法的介绍

  • 1)方法的概念:简单说就是一个对象里面的函数,称为方法。
  • 2)在go语言中,可以给任意自定义类型(包括内置类型,但不包括指针类型)添加相应的方法。
  • 3)方法总是绑定对象实例,并隐式将实例作为第一参数。
  • 4)方法的语法:
func (receiver receiverType) funcName(parameters) (results)
// 1. receiver 为任意名字。
// 2. receiverType为调用者的类型。可以是T或者*T。注意T本身不能是接口或者指针。
例如T=int,但是不能是*int。想要指针可以这样做:T=int后,单独加一个*// 代码解释:
// 1. 正确写法
type myint int
func (s *myint) Add() (r int)

// 2. 错误写法。因为T类型本身不能是指针。
type myintp *int
func (s myintp) Add() (r int)
  • 5)方法不支持重载,即不支持同样类型中,函数名相同形参不同的方法。注意,不同的类型中,是可以有同样的函数名的。下面例子将会解释到。

2 面向过程和面向对象的函数区别

非常简单,就是将函数封装到了一个对象里面,然后通过变量名 + 点的形式进行调用。利用下面的例子。

package main

import "fmt"

// go本身没有long类型
type long int

func Add01(a, b long)long{
	return a + b
}

func (t long)Add02(b long)long{
	return t + b
}

func main(){
	// 1. 面向过程
 	fmt.Println("Add01 = ", Add01(1, 2))

 	// 2. 面向对象
 	var s1 long = 1
	fmt.Println("Add02 = ", s1.Add02(5))

}

3 结构体类型添加方法

package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 带有接受者的函数叫方法
func (t Persion) PrintInfo(){
	fmt.Println("PrintInfo = ", t)
}

func (t *Persion) SetInfo(n string, s byte, a int){
	t.name = n
	t.sex = s
	t.age = a
}

func main(){

	// 1. 普通变量作为隐含实例传参
	p := Persion{"hc", 'w', 24}
	p.PrintInfo()

	// 2. 指针变量作为隐含实例传参
	(&p).SetInfo("lqq", 'w', 24)
	p.PrintInfo()
}

4 方法相关注意点

  • 1)接收者本身不能是指针类型,上面在将第1点时也强调过。
// 1. 正确的写法
type long int
func (t long)test(){
}

// 2. 错误的写法
// err:Invalid receiver type 'pointer' ('pointer' is a pointer type)
type pointer *int
func (t pointer)test(){
}
  • 2)go的方法不支持重载。例如下面这样写语法是会报错的。因为接收者的类型一样,并且名字也一样。
type long int
func (t long)test(){

}
type long int
func (t long)test(a int){

}

而下面这样写不会报错,因为接收者类型不一样。可以用C++定义了两个类,类中有同样的成员函数名去理解。

type long int
func (t long)test(){

}

type char byte
func (c char) test(a int){

}

5 接收者的值语义和引用语义

  • 1)普通变量作为接收者是值传递。
  • 2)指针变量作为接收者是引用传递。
    代码看回上面第3点的 结构体类型添加方法。

6 指针类型和变量类型的方法集

方法集实际上是使用指针可以如何调用方法,以及普通变量如何调用方法而已。变量在调用自己的方法集时,不受变量自己是指针还是普通变量的约束,都可以使用 “变量名 + 点(.) + 方法名” 的形式调用。
例如:

package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 带有接受者的函数叫方法
func (t Persion) SetInfoValue(){
	fmt.Println("SetInfoValue")
}

func (t *Persion) SetInfoPointer(){
	fmt.Println("SetInfoPointer")
}

func main(){

	// 1. 结构体变量是一个指针时,它能调用哪些方法,就是一个方法集
	// 指针调用方法的方式
	p := &Persion{"hc", 'w', 24}
	p.SetInfoPointer()
	p.SetInfoValue()	// 它内部会自动转换,将指针p转成 (*p).SetInfoValue(),所以下面的调用方式也是可以的,所以调用方法时不需要考虑是指针还是变量
	(*p).SetInfoValue()

	fmt.Println("===========")

	// 2. 普通变量调用方法的方式
	p2 := Persion{"lqq", 'w', 24}
	p2.SetInfoValue()
	p2.SetInfoPointer()	// 内部转成(&p2).SetInfoPointer(),所以下面的调用方式也是可以的
	(&p2).SetInfoPointer()
}

在这里插入图片描述

7 方法的继承

package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// Persion实现了一个方法
func (t *Persion) PrintInfo(){
	fmt.Printf("name=%s, byte=%c, age=%d\n", t.name, t.sex, t.age)
}

// 另一个结构体继承了该Persion,它会继承了所有成员及其方法
type Student struct {
	Persion // 匿名字段
	id int
	addr string
}

func main(){

	s := Student{Persion{"hc", 'w', 24}, 1, "sz"}
	s.PrintInfo()
}

8 方法的重写

go中方法的重写,实际上就是C++的多态(通过虚基类指针、virtual关键字实现)。
下面的go实现多态的例子。

package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// Persion实现了一个方法
func (t *Persion) PrintInfo(){
	fmt.Printf("name=%s, byte=%c, age=%d\n", t.name, t.sex, t.age)
}

// 另一个结构体继承了该Persion,它会继承了所有成员及其方法
type Student struct {
	Persion // 匿名字段
	id int
	addr string
}

// Student也添加一个同名的方法PrintInfo
// 注意,因为接收者类型一个是 *Persion、一个是 *Student,它们是不一样的,所以函数名可以同样。
// 这样也叫方法的重写,即实现了多态。
func (t *Student) PrintInfo(){
	fmt.Println("stu = ", t)
}


func main(){

	s := Student{Persion{"hc", 'w', 24}, 1, "sz"}

	// 根据就近原则,调用的是Student.PrintInfo()
	s.PrintInfo()

	// 显示调用才能调用到Persion的PrintInfo()
	s.Persion.PrintInfo()
}

在这里插入图片描述

9 方法值与方法表达式

  • 1)方法值:隐式调用,通过隐式保存接收者来进行调用。
  • 2)方法表达式:显示调用,不会隐式保存接收者,调用时需要显示传实例给对应的接收者类型。

代码例子:

package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 带有接受者的函数叫方法
func (t Persion) SetInfoValue(){
	fmt.Println("SetInfoValue")
}

func (t *Persion) SetInfoPointer(){
	fmt.Println("SetInfoPointer")
}

func main(){

	// 1. 方法值调用
	p := &Persion{"hc", 'w', 24}
	pFunc := p.SetInfoPointer				// 会隐式保存接收者
	pFunc()

	vFunc := p.SetInfoValue
	vFunc()

	fmt.Println("==============")

	// 2. 方法表达式调用
	p2 := Persion{"lqq", 'w', 24}
	f := (*Persion).SetInfoPointer			// 不会隐式保存接收者,所以调用时需要传对应的实例给接收者。(*Persion)表示传实例时是一个地址而不是普通变量。
	f(&p2)									// 需要传实例给接收者类型。

	f2 := (Persion).SetInfoValue			// Persion表示传实例时是一个普通变量而不是地址。
	f2(p2)									// 需要传实例给接收者类型。
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go语言基础-----07-----方法 的相关文章

  • 当涉及多个渠道时,select 如何工作?

    我发现在多个非缓冲通道上使用 select 时 例如 select case lt chana case lt chanb 即使两个通道都有数据 但在处理此选择时 case chana 和 case chanb 的跟注不平衡 package
  • GoQt 致命错误:QAbstractAnimation:没有这样的文件或目录

    我尝试编译 Qt 来开发桌面应用程序 我按照 Qt 网站上的官方 wiki 指南的说明进行操作 当我尝试go run示例文件夹中的示例 我收到错误 去运行 home pinkya rabbit workspace go1programs s
  • 为什么我不能将左大括号放在下一行?

    当我尝试编译以下代码时遇到奇怪的错误 package main import fmt fmt func main var arr 3 int for i 0 i lt 3 i fmt Printf d arr i 错误如下 unexpect
  • go中有memset的类似物吗?

    在 C 中 我可以使用某些值初始化数组memset https msdn microsoft com en us library aa246471 28v vs 60 29 aspx const int MAX 1000000 int is
  • 在 Go 中初始化嵌入结构

    我有以下内容struct其中包含一个net http Request type MyRequest struct http Request PathParams map string string 现在我想初始化匿名内部结构http Req
  • 如何将 SQLite 数据库捆绑到 Go 二进制文件中?

    我尝试使用 go bindata 和 packr 但这些包没有显示如何将 SQLite 数据库文件打包到二进制文件中 我不需要以任何方式更新数据库 我只想在启动时从中读取数据 如何将 SQLite 数据库文件嵌入到 Go 二进制文件中 SQ
  • 正确的文件扩展名或缩写是什么。 golang 的文本/模板?

    我正在考虑为其创建语法荧光笔 但我不知道这种特定类型模板的常规缩写 In 例子之一 http golang org pkg text template example Template helpers从文本 模板 godoc 中 它们引用
  • “go.tools”的权限被拒绝错误

    当我尝试安装 go 工具时 我的权限被拒绝 usr local go pkg tool linux amd64 cover 我可以接受 因为它是 usr local 目录及需求root使用权 但我的第一个疑问是为什么当我设置时它试图安装在这
  • 将 time.Time 转换为字符串

    我正在尝试将数据库中的一些值添加到 string在围棋中 其中一些是时间戳 我收到错误 无法在数组元素中使用 U Created date 类型 time Time 作为类型字符串 我可以转换吗time Time to string typ
  • 为什么 json.Unmarshal 返回映射而不是预期的结构?

    看看这个游乐场 http play golang org p dWku6SPqj5 http play golang org p dWku6SPqj5 基本上 我正在工作的图书馆收到了interface 作为参数 然后需要json Unma
  • 直接从一个通道发送到另一个通道

    当从一个通道直接发送到另一个通道时 我偶然发现了令人惊讶的行为 package main import fmt func main my chan make chan string chan of chans make chan chan
  • 如何同时使用 LoadHTMLGlob 和 LoadHTMLFiles

    我想要来自不同子目录的分隔符逻辑模板templates文件夹 下面是我的templates文件夹 templates authentication login gohtml logout gohtml index gohtml profil
  • select 语句是否保证通道选择的顺序?

    继从这个答案 https stackoverflow com a 25795236 274460 如果一个 goroutine 在两个通道上进行选择 是否保证通道的选择顺序与其发送的顺序相同 我对发送者是单线程的情况特别感兴趣 例如 是否保
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • 如何将接口转换为接口切片?

    我的输入是interface 而且我知道它可以是任何类型的数组 我想读取我输入的元素之一 所以我尝试将我的interface 进入一个 interface 但是 go 会给我以下错误 恐慌 接口转换 interface 是 map stri
  • 为什么 gmail API 以纯文本形式发送 html 电子邮件?

    我正在尝试使用 gmail API 发送 html 电子邮件 但由于某些原因 它会随机以纯文本 文本形式发送电子邮件 谷歌似乎改变了我设置的内容类型标头 这有什么理由吗 电子邮件内容始终完全相同 正如我测试的那样 API 仍处于实验阶段吗
  • 是否可以在 C/C++ 中模仿 Go 接口?

    在 Go 中 如果类型具有接口定义的所有方法 则可以将其分配给该接口变量 而无需显式继承它 是否可以在 C C 中模仿此功能 是的 您可以使用纯抽象类 并使用模板类来包装 实现 抽象类的类型 以便它们扩展抽象类 这是一个简单的示例 incl
  • 实现具有更广泛方法签名的接口

    在Go中 是否有一种方法可以使用方法来实现接口 其中实现中相应方法的返回类型 比 预期返回类型 更宽 这很难解释 所以这里有一个例子 在 Go Playground 中运行以下示例代码时出现此错误 prog go 36 14 cannot
  • 什么时候返回结构体指针是个好主意?

    我正在学习 Go 我对何时使用指针有点困惑 具体来说 当返回一个struct从函数中 什么时候适合返回结构体实例本身 什么时候适合返回指向结构体的指针 示例代码 type Car struct make string model strin
  • Go客户端程序生成大量TIME_WAIT状态的socket

    我有一个 Go 程序 它从多个 goroutine 生成大量 HTTP 请求 运行一段时间后 程序报错 connect cannot allocaterequestedaddress 当检查时netstat 我得到大量 28229 个连接T

随机推荐

  • SpringCloud学习笔记(二)

    续 一 负载均衡的第二种实现方式Feign 前面在使用Ribbon RestTemplate时 利用RestTemplate对Http请求的封装处理 形成了一套模板化的调用方法 但是使用 RestTemplate 还是不方便 这样每次都调用
  • 87-信号和槽-基于Qt Designer 的信号与槽

    基于Qt Designer 的信号与槽 可以使用 Qt Designer 创建信号与槽 这种方式的好处是可以可视化创建页面视图 少写很多代码 只需要关注逻辑部分就可以 本节案例要实现的功能如下 通过一个模拟打印的界面来详细说明信号的使用 在
  • Flutter的手势识别功能实现GestureDetector

    GestureDetector简介 GestureDetector 是 Flutter 中一个非常常用的小部件 它提供了许多手势识别的功能 包括点击 双击 长按 拖动 缩放等等 使用方法 GestureDetector 可以包裹其他部件 当
  • jenkins pipeline中获取shell命令的标准输出或者状态

    获取标准输出 第一种 result sh returnStdout true script
  • args在python中什么意思_Python中*args、**args到底是什么、有啥区别、怎么用

    调用函数时使用 和 假设有函数 def test a b c test args 的作用其实就是把序列 args 中的每个元素 当作位置参数传进去 比如上面这个代码 如果 args 等于 1 2 3 那么这个代码就等价于 test 1 2
  • BUUCTF-[Misc杂项]---二维码

    目录 BUUCTF Misc杂项 二维码 题目 题解 BUUCTF Misc杂项 二维码 题目 题解 下载附加压缩包并打开 打开后发现是一张png图片 解压下来 解压后是一张二维码图片 我们直接放到二维码查看器工具当中 得到此条信息 我们继
  • c# global::

    Global 表示所有命名空间的根部 Global asa 文件的作用主要是用于站点或虚拟目录下程序的数据共享和多线程 在 global asa 中 可以声明 Application 事件和 Session 事件 并可以声明一些 Sessi
  • Windows安装pip方法

    pip是一款非常方便的python包管理工具 本文主要介绍在windows 10下安装pip方法 1 下载pip 地址 https pypi python org pypi pip downloads 注意选择tar gz压缩包 目前最新版
  • 服务器系统版本选择,云服务器选择系统版本

    云服务器选择系统版本 内容精选 换一换 使用弹性云服务器或者外部镜像文件创建私有镜像时 必须确保操作系统中已安装PV driver 使新发放的云服务器支持XEN虚拟化 同时也可以提升云服务器的I O处理性能 实现对云服务器硬件的监控和其他高
  • MobileNet ShuffleNet & yolov5替换backbone

    以下内容参考参考 MobileNet V1 亮点 1 使用可分离卷积核大幅减少参数量 2 增加了超参数a b a 卷积核个数的倍率 b 分辨率高低 MobileNet V2 亮点 1 使用倒结构残差 残差结构 两边粗 中间细 倒残差结构 两
  • uniapp为page设置背景色不生效 & lang=“scss“ scoped的page样式失效,uniapp重复打开页面

    一 lang scss scoped中的page选择器的样式失效 在用uniapp生成网页和H5时有效 但生成小程序或者app时无效 这是因为page选择器在小程序和app编译中是页面的父节点 所以加上scoped限定后 会导致无法选中 详
  • 《Centos6.5——图形化安装虚拟机》

    目录 安装虚拟机以及虚拟机的配置 1 先下载镜像 2 安装VMware Workstation 3 打开vm 点击创建新的虚拟机 1 一路下一步 直到选择镜像 2 继续下一步 直到如下图 选择CD 选择镜像后点击确定 然后点击开启虚拟机 3
  • 阿里云-云存储OSS

    1 简述OSS 数据的可靠性较强 三重备份 系统的安全性较强 对称加密 签名权限控制以及防盗链功能 文件存储的容量无限 无需人工运维 部署扩容 无需规则 按需扩容 提供丰富的API接口 SDK包 客户端工具台 控制台 方便应用程序调用 安全
  • 基于Python和mysql开发的今天吃什么微信小程序(源码+数据库+程序配置说明书+程序使用说明书)

    一 项目简介 本项目是一套基于Python和mysql开发的今天吃什么微信小程序 主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者 包含 项目源码 项目文档 数据库脚本等 该项目附带全部源码可作为毕设使用 项目
  • 【深度学习】池化 (pooling)

    深度学习中 有两种实现非线性的算子 一个是激活函数 另一个就是池化 pooling 在知乎上面看到一个关于池化的神解释 摘来 池化 涨水 卷积的目的是为了得到物体的边缘形状 可以想象水要了解山立体的形状 水位低时得出山脚的形状 水位中等时得
  • 信息安全—密码学信息熵信息理论基础—熵的概念(熵、联合熵、条件熵、平均互信息)

    数学基础 概率论乘法法则 两个事件相互独立 P A B P A P B 意思是事件A和事件B同时发生的概率 事件A发生的概率 事件B发生的概率 举个栗子 掷两枚硬币硬币同时立着的概率 掷一枚硬币立着的概率 再掷一枚 硬币立着的概率 两个事件
  • Partition List

    题目 Given a linked list and a value x partition it such that all nodes less than x come before nodes greater than or equa
  • 关于免费获得WPS会员自动邀请助力的JAVA项目分享

    WPS自动邀请说明 一 基本说明 本项目不是全自动 需要用户每日13点前在微信WPS会员公众号完成在线签到 再完成签到后即可输入自己uid完成自动拉满10人的任务 本项目仅用于学习 不用于商业 二 具体步骤 添加微信公众号WPS会员 福利
  • python编程标准化_Python数据预处理:彻底理解标准化和归一化

    数据预处理 数据中不同特征的量纲可能不一致 数值间的差别可能很大 不进行处理可能会影响到数据分析的结果 因此 需要对数据按照一定比例进行缩放 使之落在一个特定的区域 便于进行综合分析 常用的方法有两种 最大 最小规范化 对原始数据进行线性变
  • go语言基础-----07-----方法

    1 方法的介绍 1 方法的概念 简单说就是一个对象里面的函数 称为方法 2 在go语言中 可以给任意自定义类型 包括内置类型 但不包括指针类型 添加相应的方法 3 方法总是绑定对象实例 并隐式将实例作为第一参数 4 方法的语法 func r