Golang——方法

一. 方法定义

        Golang方法总是绑定对象的实例,并隐式将实例作为第一实参。

  • 只能为当前包内命名类型定义方法
  • 参数receiver可以任意命名。如方法中未曾使用,可省略参数名
  • 参数receiver类型可以是T或*T。基类型T不能是接口或指针类型(即多级指针)
  • 不支持方法重载,receiver只是参数前面的组成部分
  • 可用实例value或pointer调用全部方法,编译器自动转换

        一个方法就是一个包含接收者(receiver)的函数,接收者(receiver)可以是命名类型或者结构体类型的一个值或者是一个指针。

        所有给定类型的方法属于该类型的方法集。

        1.1 方法定义

func (reveicer type) methodName(参数列表)(返回值列表){}//参数和返回值可以省略
package maintype test struct{}// 接收者为值类型,无参,无返回值
func (t test) method0() {}// 接收者为值类型,单参,无返回值
func (t test) method1(x int) {}// 接收者为值类型,无参,单返回值
func (t test) method2() (res int) { return }// 接收者为值类型,多参,无返回值
func (t test) method3(x, y int) {}// 接收者为值类型,无参,多返回值
func (t test) method4() (res1, res2 int) { return }// 接收者为值类型,多参,多返回值
func (t test) method5(x, y int) (res1, res2 int) { return }// 接收者为指针类型,无参,无返回值
func (t *test) method6() {}// 接收者为指针类型,单参,无返回值
func (t *test) method7(x int) {}// 接收者为指针类型,无参,单返回值
func (t *test) method8() (res int) { return }// 接收者为指针类型,多参,无返回值
func (t *test) method9(x, y int) {}// 接收者为指针类型,无参,多返回值
func (t *test) method10() (res1, res2 int) { return }// 接收者为指针类型,多参,多返回值
func (t *test) method11(x, y int) (res1, res2 int) { return }func main(){}

下面定义了一个结构体类型和它的方法。

        解释:首先我们定义了一个叫做User的结构体类型,然后定义了一个该类型的方法Notice,该方法的接收者是一个User类型的值。要调用Notice方法,我们需要一个User类型的值或者指针。 

        在例子中,当我们使用指针时,Go调整成解引用使得调用可以被执行。

        注意:当接收者不是一个指针时,该方法操作对应接收者值的副本。意思是即使你使用指针调用方法,但方法的接收者是值类型,方法内部的操作还是对副本进行操作,不会修改原来的值。

         我们修改Notice方法,让他的接收者变成指针类型。

        注意:当接收者是指针,即使使用值类型调用方法,方法内部也是对指针操作。会修改原来的值。

  • 方法不过是特殊的函数,只需要将其还原,就知道receiver T和*T的差别

        1.2 普通函数与方法区别

  • 对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
  • 对于方法,接收者为值类型,可以直接使用指针类型的变量调用方法,反过来也可以。
package mainimport "fmt"//普通函数
//接收者为值类型
func valueIntTest(a int) int {return a + 10
}//接收者为指针类型
func pointIntTest(a *int) int {return *a + 10
}func testValue() {a := 10fmt.Println(valueIntTest(a))//不能传递指针 如:valueIntTest(&a)b := 20fmt.Println(pointIntTest(&b))//不能传递值 如:pointIntTest(b)
}//结构体
type Data struct {x int
}func (d Data) valueShowData() {fmt.Println(d.x)
}func (d *Data) pointShowData() {fmt.Println(d.x)
}func testStruct() {//值类型调用方法d1 := Data{x: 10}d1.valueShowData()d1.pointShowData()//指针类型调用方法d2 := &Data{x: 100}d2.valueShowData()d2.pointShowData()
}func main() {testValue()testStruct()
}

二. 匿名字段

        Golang匿名字段:可以像字段成员那样访问匿名字段方法,编译器负责查找。

        Go语言是通过嵌套来实现继承的,依据编译器查找次序,只需要在外层定义同名方法,就可以实现继承的隐藏。

三. 方法集

        Golang的方法集:每个类型都有与之关联的方法集,这会影响到接口的实现规则。

  • 类型T方法集包含全部receiver T的方法
  • 类型*T方法集包含全部receiver T + *T方法
  • 如类型S包含匿名字段T,则S和*S方法集包含T的方法
  • 如类型S包含匿名字段*T,则S和*S方法集包含T + *T方法
  • 不管嵌入T或*T,*S方法集总是包含T + *T方法

        用实例value和pointer调用方法(含其它自定义类型)不受方法集的约束,编译器总是查找全部方法,并自动转换reveiver实参。

        方法集和调用方法没有关系。方法集是Go语言中实现面向对象编程特性的关键概念之一,它允许开发者为自定义类型定义行为,并通过接口来实现多态。同时,方法集也是Go语言类型系统和接口系统中不可或缺的一部分。

  • Go语言中内部类型方法提升的规则

        类型T方法集包含全部receiver T的方法。

        类型*T方法集包含全部receiver T + *T方法。

        给定结构体类型S和一个命名为T的类型,方法提升像下面规定的这样被包含在结构体方法集中:

        如类型S包含匿名字段T,则S和*S方法集包含T方法。

        这条规则说的是当我们嵌入一个值类型嵌入类型的接收者为值类型的方法将被提升,可以被外部类型的值和指针调用。

        如类型S包含匿名字段*T,则S和*S方法集包含T+*T方法。

        这条规则说的是当我们嵌入一个类型的指针,嵌入类型的接收者为值类型或者指针类型的方法将被提升,可以被外部类型的值或指针调用

四. 表达式

        Golang表达式:根据调用者不同,方法分为两种表现形式。

  1. object.method(arg...)
  2. type.method(arg...)

        前者称为method value,后者method expression。两者都可像普通函数那样赋值和传参,区别在于method value绑定实例,而method expression则需显示传参。

  •  method value会复制receiver

在汇编层面上,method value和闭包的实现方式相同,实际返回FuncVal类型对象。

FuncVal { method_address, receiver_copy }
  • 可依据方法集转换method expression,注意receiver类型的差异

  • 将方法还原成函数,就是下面的代码
package maintype User struct{}func (User) TestValue() {}func (*User) TestPoint() {}func main() {var u *User = nilu.TestPoint()(*User)(nil).TestPoint() //method value,对象为nil(*User).TestPoint(nil)   //method expression,传的对象为nil
}

五. 自定义error

        5.1 抛异常和处理异常

        5.1.1 抛异常

package mainimport "fmt"//系统抛异常
func test01() {a := [5]int{1, 2, 3, 4}a[1] = 123fmt.Println(a)index := 10a[index] = 10fmt.Println(a)
}func getCircleArea(radius float32) float32 {if radius < 0 {panic("半径不能为负") //自己抛异常}return 3.14 * radius * radius
}func test02() {getCircleArea(-5)
}//捕获异常
func test03() {//回收异常defer func() {if err := recover(); err != nil {fmt.Println(err)}}()test02()fmt.Println("这里不执行")
}func test04() {test03()fmt.Println("test04")
}func main() {test04()test01()
}

        5.1.2 返回异常

        5.2 自定义错误

 

 

 

        

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/802817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024.4.5-day10-CSS 布局模型(层模型)

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 2024.4.5-学习笔记1 CSS定位1.1 相对定位 relative1.2 绝对定位 absolut…

多乐空气处理设备有限公司现已加入2024第13届生物发酵展

参展企业介绍 为满足日益发展的中国大陆市场对环境的要求&#xff0c;更接近最终用户&#xff0c;多乐集团于2001年在上海松江设立了第一家生产基地。经过十数年来的高速发展&#xff0c;多乐以其精湛的加工工艺、一流的制造技术方面的优势&#xff0c;在对温度湿度有严格要求…

赛氪网|2024中国翻译协会年会“AI科技时代竞赛与就业”分论坛

在2024年中国翻译协会年会期间&#xff0c;赛氪网与中西部翻译协会共同体多边合作平台共同承办&#xff0c;于3月30日下午在长沙成功举办了“AI科技时代竞赛与就业分论坛”。该论坛汇聚了众多翻译界、科技界和教育界的专家学者&#xff0c;共同探讨科技、实践、就业与竞赛人才培…

秋招算法刷题6

20240408 1.两数之和 &#xff08;时间复杂度是O&#xff08;n的平方&#xff09;&#xff09; public int[] twoSum(int[] nums, int target){int nnums.length; for(int i0;i<n;i){ for(int j1;j<n;j){ if(nums[i][j]target){ …

springboot3使用自定义注解+AOP+redis优雅实现防重复提交

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途 目录 写在前面 实现思路 实现步骤 1.定义防重复提交注解 2.编写一个切面去发现该注解然后执行防重复提交逻辑 3.测试 …

RAGFlow:基于OCR和文档解析的下一代 RAG 引擎

一、引言 在人工智能的浪潮中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势成为了研究和应用的热点。RAG技术通过结合大型语言模型&#xff08;LLMs&#xff09;的强大生成能力和高效的信息检索系统…

书生·浦语大模型实战营 | 第2次学习笔记

前言 书生浦语大模型应用实战营 第二期正在开营&#xff0c;欢迎大家来学习。&#xff08;参与链接&#xff1a;课程升级&#xff0c;算力免费&#xff0c;书生浦语实战营第二期学员招募&#xff5c;活动预告https://mp.weixin.qq.com/s/YYSr3re6IduLJCAh-jgZqg&#xff09; …

GFS部署实验

目录 1、部署环境 ​编辑 2、更改节点名称 3、准备环境 4、磁盘分区&#xff0c;并挂载 5. 做主机映射--/etc/hosts/ 6. 复制脚本文件 7. 执行脚本完成分区 8. 安装客户端软件 1. 创建gfs 2. 安装解压源包 3. 安装 gfs 4. 开启服务 9、 添加节点到存储信任池中 1…

SpringBoot项目如何国际化操作,让你可以随意切换语言

1.前言 最近接触的项目需要中文/英文或者其他国家语言的切换&#xff0c;在后台的时候有一个选择&#xff0c;你可以选择中文还是英文&#xff0c;或者其他语言&#xff0c;选择完毕界面语言就都变了&#xff0c;咱不知道前端怎么操作的&#xff0c;但是后台在处理提示语的时候…

软件SPI读写W25Q64

文章目录 前言接线引脚定义图 软件SPI读写W25Q64代码规划代码实现ThisSPI.cThisW25Q64.cmain.c 前言 SPI介绍&#xff1a;https://blog.csdn.net/qq_53922901/article/details/137142038 W25Q64介绍&#xff1a; https://blog.csdn.net/qq_53922901/article/details/137197048…

C++性能测试工具

使用示例main.cpp // g-13 -O3 -stdc17 main.cpp profile.cpp #include <iostream> #include <chrono> #include <stdint.h> #include <mutex> // std::mutex#include "profile.h" #include "profile_rdtsc.h"std::mut…

Java基于SpringBoot+Vue 的医院预约挂号系统

博主介绍&#xff1a;✌程序员徐师兄、10年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447…

【问题记录】使用Audition播放时低8位数据会被修改

一&#xff0c;问题现象记录 使用Audition连接UAC播放采样点数据比较大的时候&#xff0c;低8位的数据会被修改。如果对低8位数据敏感的情况&#xff0c;需要使用其他播放器进行播放。 二&#xff0c;问题复现 1&#xff0c;使用C代码生成一个PCM文件&#xff1a; #include…

智慧水库解决方案(打造水库智慧监测体系)

​作为一名水利自动化系统集成商,最近我司接手了一个智慧水库建设项目。这个项目位于一座山区的大型水库,目的是对其进行现代化、智能化改造,提升供水、防洪等管理水平。&#xff08;key-iot.com.cn&#xff09; 在方案设计之初,我们组织了现场勘测,全面了解水库的实际情况。这…

win11系统和ubuntu双系统首次连接网线上网流程

硬件准备 首先需要将网线连接到电脑&#xff0c;另一头可以连接交换机或者路由器 上网前需要拨号上网&#xff0c;如果是连的路由器&#xff0c;那么一台路由器上拨号一次就行了。 如果是连的交换机需要拨号上网 这里踩的第一个坑是刚开始电脑连的是交换机1又连的交换机2&…

STM32中C编程引入C++程序

C具备类的创建思想很实用于实际场景多相似性的框架搭建&#xff1b;同种类型或相似类型的C的优势明显因此进行相互嵌套使用 需要在C中使用C类的话&#xff0c;你可以通过C的“extern "C"”语法来实现。这允许你在C代码中使用C的链接方式&#xff0c;而在C代码中使用…

【Linux】UDP编程【上】{诸多编程接口/小白入门式讲解}

文章目录 0.预备知识0.1套接字0.2TCP/UDP0.3大小端问题 1.socket 常见API1.1socket1.2各个接口1.3int bind();1.3网络头文件四件套1.4bzero1.5recvfrom1.6sendto() 2.UDP编程2.1服务器编程2.2客户端编程2.3运行测试2.3.1本机通信2.3.2popen2.3.3strcasestr2.3.4回顾C11智能指针…

微电网优化:基于肝癌算法(Liver Cancer algorithm, LCA)的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…

Mamba解读(FlashAttention,SSM,LSSL,S4,S5,Mamba)

Sequence modelScale and EfficiencyFlashAttentionMotivationMethodFlashDecoding MambaState-Space Models&#xff08;SSM&#xff09;Selective State Space Models&#xff08;Mamba&#xff09; Sequence model seq2seq任务将 输入序列 x ( t ) x(t) x(t) 映射为 输出序…

每日两题 / 1.两数之和 49.字母异位词分组(leetcode热题100)

1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 暴力解法&#xff1a; O ( N 2 ) O(N^2) O(N2)遍历数组&#xff0c;找两个数相加为target O ( N ) O(N) O(N)解法&#xff1a;将所有数排序&#xff0c;并记录这些数的下标&#xff0c;双指针从左右向中间走。指向的两数…