go方法定义

方法定义

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

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

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

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

1.1.1. 方法定义:

func (recevier type) methodName(参数列表)(返回值列表){}参数和返回值可以省略
package maintype Test struct{}// 无参数、无返回值
func (t Test) method0() {}// 单参数、无返回值
func (t Test) method1(i int) {}// 多参数、无返回值
func (t Test) method2(x, y int) {}// 无参数、单返回值
func (t Test) method3() (i int) {return
}// 多参数、多返回值
func (t Test) method4(x, y int) (z int, err error) {return
}// 无参数、无返回值
func (t *Test) method5() {}// 单参数、无返回值
func (t *Test) method6(i int) {}// 多参数、无返回值
func (t *Test) method7(x, y int) {}// 无参数、单返回值
func (t *Test) method8() (i int) {return
}// 多参数、多返回值
func (t *Test) method9(x, y int) (z int, err error) {return
}func main() {}

下面定义一个结构体类型和该类型的一个方法:

package mainimport ("fmt"
)//结构体
type User struct {Name  stringEmail string
}//方法
func (u User) Notify() {fmt.Printf("%v : %v \n", u.Name, u.Email)
}
func main() {// 值类型调用方法u1 := User{"golang", "golang@golang.com"}u1.Notify()// 指针类型调用方法u2 := User{"go", "go@go.com"}u3 := &u2u3.Notify()
}

输出结果:

    golang : golang@golang.com go : go@go.com

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

在这个例子中当我们使用指针时,Go 调整和解引用指针使得调用可以被执行。注意,当接受者不是一个指针时,该方法操作对应接受者的值的副本(意思就是即使你使用了指针调用函数,但是函数的接受者是值类型,所以函数内部操作还是对副本的操作,而不是指针操作。

我们修改 Notify 方法,让它的接受者使用指针类型:

package mainimport ("fmt"
)//结构体
type User struct {Name  stringEmail string
}//方法
func (u *User) Notify() {fmt.Printf("%v : %v \n", u.Name, u.Email)
}
func main() {// 值类型调用方法u1 := User{"golang", "golang@golang.com"}u1.Notify()// 指针类型调用方法u2 := User{"go", "go@go.com"}u3 := &u2u3.Notify()
}

输出结果:

    golang : golang@golang.com go : go@go.com

注意:当接受者是指针时,即使用值类型调用那么函数内部也是对指针的操作。

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

package mainimport "fmt"type Data struct {x int
}func (self Data) ValueTest() { // func ValueTest(self Data);fmt.Printf("Value: %p\n", &self)
}func (self *Data) PointerTest() { // func PointerTest(self *Data);fmt.Printf("Pointer: %p\n", self)
}func main() {d := Data{}p := &dfmt.Printf("Data: %p\n", p)d.ValueTest()   // ValueTest(d)d.PointerTest() // PointerTest(&d)p.ValueTest()   // ValueTest(*p)p.PointerTest() // PointerTest(p)
}

输出:

    Data: 0xc42007c008Value: 0xc42007c018Pointer: 0xc42007c008Value: 0xc42007c020Pointer: 0xc42007c008

1.1.2. 普通函数与方法的区别

1.对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然。

2.对于方法(如struct的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以。

package main//普通函数与方法的区别(在接收者分别为值类型和指针类型的时候)import ("fmt"
)//1.普通函数
//接收值类型参数的函数
func valueIntTest(a int) int {return a + 10
}//接收指针类型参数的函数
func pointerIntTest(a *int) int {return *a + 10
}func structTestValue() {a := 2fmt.Println("valueIntTest:", valueIntTest(a))//函数的参数为值类型,则不能直接将指针作为参数传递//fmt.Println("valueIntTest:", valueIntTest(&a))//compile error: cannot use &a (type *int) as type int in function argumentb := 5fmt.Println("pointerIntTest:", pointerIntTest(&b))//同样,当函数的参数为指针类型时,也不能直接将值类型作为参数传递//fmt.Println("pointerIntTest:", pointerIntTest(b))//compile error:cannot use b (type int) as type *int in function argument
}//2.方法
type PersonD struct {id   intname string
}//接收者为值类型
func (p PersonD) valueShowName() {fmt.Println(p.name)
}//接收者为指针类型
func (p *PersonD) pointShowName() {fmt.Println(p.name)
}func structTestFunc() {//值类型调用方法personValue := PersonD{101, "hello world"}personValue.valueShowName()personValue.pointShowName()//指针类型调用方法personPointer := &PersonD{102, "hello golang"}personPointer.valueShowName()personPointer.pointShowName()//与普通函数不同,接收者为指针类型和值类型的方法,指针类型和值类型的变量均可相互调用
}func main() {structTestValue()structTestFunc()
}

输出结果:

    valueIntTest: 12pointerIntTest: 15hello worldhello worldhello golanghello golang

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

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

相关文章

试用NXP官方的UDS bootloader

文章目录 1.前言2.资料获取2.1 MCU例程 2.2 开发环境2.3 上位机2.4 硬件 3.工程修改3.1 boot工程修改 3.2 app工程修改4.测试情况5.例程分享 1.前言 最近很多客户在开发S32K系列MCU时咨询是否可以提供基于UDS协议的bootloader。本文以S32K144为例,介绍如何使用NXP官…

qt基础类型转换

uchar*与QByteArray类型 uchar转为QByteArray QByteArray array; unsigned char buf ; arrayQByteArray::fromRawData((char)buf,sizeof(buf)); QByteArray转为uchar //一次性转换 buf reinterpret_cast<unsigned char*>(array.data()); //单个数据转换 (unsigned cha…

【Mybatis操作数据库】入门(一)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MyBatis框架】 本专栏旨在分享MyBatis框架的学习笔记&#xff0c;如有错误定当洗耳恭听&#xff0c;欢迎大家在评论区交流讨论&#x1f…

NGINX App Protect现已支持NGINX开源版 全方位加强现代应用安全防护

近日&#xff0c;F5 NGINX 发布全新升级的NGINX App Protect 5.0版本&#xff0c;将先前专属于NGINX 商业版本NGINX Plus 的现代应用安全能力拓展至NGINX开源版中&#xff0c;为增强现代应用和API安全防护提供全方位支持。此次升级后&#xff0c;适用于云端及本地部署的NGINX A…

软考中级之数据库系统工程师笔记总结(六)多媒体基础

作者&#xff1a;Maynor 博客之星大数据领域Top1,GitHub项目awesome-chatgpt-project作者, 大厂程序员, 全网技术矩阵粉丝7w 公众号&#xff1a;Maynor996&#x1f4e2;博客主页&#xff1a;https://manor.blog.csdn.net &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &am…

基于TL431的线性可调恒压恒流电源的Multisim电路仿真设计

1、线性电源的工作原理 在我们日常应用里&#xff0c;直流电是从市电或电网中的交流电获取的。例如15V直流电压源、24V直流电压源等等。交流电变为直流电的过程大概分为一下几步&#xff1a; 首先&#xff0c;交流电通过变压器降低其电压幅值。接着&#xff0c;经过整流电路进…

【jetson】研华 jetson orin 开发套件系统镜像下载链接、刷入镜像时修改默认用户名的方法

1. 系统镜像下载链接 orin nano 8G&#xff1a;https://pan.baidu.com/s/1iE6ES5yV8CQ85HU0O34mHg?pwdmoyk orin nx 8G&#xff1a;https://pan.baidu.com/s/1F96NN1Hy0meNegzuqW-7mA?pwdqojr orin nx 16G&#xff1a;https://pan.baidu.com/s/1w0Gukoi9Ld-8wZLKQuhcgQ?pwd…

韩顺平0基础学Java——第6天

p87-p109 运算符&#xff08;第四章&#xff09; 四种进制 二进制用0b或0B开头 十进制略 八进制用0开头 十六进制0x或0X开头&#xff0c;其中的A—F不区分大小写 10转2&#xff1a;将这个数不断除以2&#xff0c;直到商为0&#xff0c;然后把每步得到的余数倒过来&#…

储能液冷系统中的管路介绍

储能液冷系统中管路占比约10%。储能液冷管路通过向系统中导入冷却剂&#xff0c;使产热元件与冷却剂进行换热&#xff0c;有效提高能源转化效率&#xff0c;并维持系统的温度稳定。 近年来液冷储能市场的兴起&#xff0c;也为尼龙管路打开了新的市场。储能液冷循环管路按照作用…

【GaussTech速递】数据库技术解读之细粒度资源管控

背景 对数据库集群内资源管控与资源隔离一直是企业客户长久以来的诉求。华为云GaussDB作为一款企业级分布式数据库&#xff0c;一直致力于满足企业对大型数据库集群的管理需要。 数据库可以管理的资源有计算资源与存储资源&#xff0c;计算资源包括CPU、内存、IO与网络&#…

【AI大模型】AI大模型热门关键词解析与核心概念入门

&#x1f680; 作者 &#xff1a;“大数据小禅” &#x1f680; 文章简介 &#xff1a;本专栏后续将持续更新大模型相关文章&#xff0c;从开发到微调到应用&#xff0c;需要下载好的模型包可私。 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 目…

【大模型赋能开发者】海云安入选数世咨询LLM驱动数字安全2024——AI安全系列报告

近日&#xff0c;国内知名数字产业领域第三方调研咨询机构数世咨询发布了LLM驱动数字安全2024——AI安全系列报告。报告通过调研、公开信息收集等方式对目前十余家已具备LLM相关的应用能力安全厂商对比分析出了这一领域当前的产业现状并进行了各厂商的能力展示。 海云安凭借近…

通过网络服务远程调用NVIDIA RTX系列GPU资源

摘要&#xff1a; 随着计算需求的增加&#xff0c;利用GPU进行计算加速已成为提高效率的关键。NVIDIA RTX系列GPU因其出色的性能被广泛用于各种计算密集型任务。本文提供了一套详细的指南&#xff0c;介绍如何在Windows和Linux服务器上通过网络服务远程调用RTX GPU资源&#xf…

C# SolidWorks 二次开发 -从零开始创建一个插件(3) 发布插件

五一节过完了吧&#xff0c;该上班学习了吧&#xff1f; 如何把自己开发好的程序优雅的给别人使用。 今天我们来简单讲解一下&#xff0c;这个之前不少粉丝咨询过相关问题&#xff0c;自己开发好的东西&#xff0c;如何给同事或者其它人使用。 先列一下使用到的主要工具&am…

使用.NET8实现Web API

目录 1、环境准备1.1、从官网下载及安装VS2022社区版1.2、下载及安装asp.net core的运行时及IIS Module 2、WebAPI工程创建2.2 推荐的库2.2.1 数据库篇2.2.1.1、 SQLSugar2.2.1.2、 OracleAccess 2.2.2、IOC篇2.2.2.1、autofac2.2.2.2、 2.2.3、日志记录篇2.2.3.1 log4net2.2.3…

C++ 智能指针使用

智能指针是C中用于自动管理动态分配内存的机制&#xff0c;它们通过确保在适当的时候删除对象来避免内存泄漏。 在C11及以后的版本中&#xff0c;有三种主要的智能指针&#xff1a;std::unique_ptr、std::shared_ptr和std::weak_ptr。 以下是这些智能指针之间的区别、优缺点以…

Ubuntu 20.04 安装 Ansible

使用官方的 Ubuntu PPA 更新包列表&#xff1a; apt update安装软件属性常用命令 apt install software-properties-common添加 Ansible PPA 到系统&#xff1a; add-apt-repository --yes --update ppa:ansible/ansible再次更新包列表以包括新添加的 PPA&#xff1a; apt …

【Linux】Centos7安装部署unimrcp,搭建MRCP服务器

yum install libtool yum install libtool-ltdl-devel yum install libsofia-sip-ua find / -name libsofia-sip-ua.so.0 2>/dev/null # 设置环境变量&#xff1a;如果库文件存在但不在默认搜索路径中&#xff0c;你可以通过设置 LD_LIBRARY_PATH 环境变量来告诉系统在哪…

Python中的函数定义(def)详解

Python中的函数定义&#xff08;def&#xff09;详解 在编程语言中&#xff0c;函数是组织代码的一种方式&#xff0c;它们可以帮助我们将复杂的程序拆分为简单、易管理的部分。在Python中&#xff0c;函数的定义使用def关键字。 什么是函数&#xff1f; 函数是一段完成特定…

【微信小程序开发】微信小程序、大前端之flex布局方式详细解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…