golang学习笔记20-面向对象(二):方法与结构体【重要】

本节内容是面向对象的核心与基础,很重要。
注意:由于导包语句已经在19讲(笔记19:面向对象的引入)展示过了,所以这里就不展示了。

一、方法的定义与细节

方法是与特定类型(通常是结构体)关联的函数。方法可以操作该类型的实例,并且可以使用其字段。定义方法时,需要指定一个接收者(receiver),这使得方法能够访问该接收者的属性。语法如下:

func (receiver TypeName) MethodName(parameters) returnList {
    // 方法体
}

receiver是接收者的名称,类型是你想要关联的自定义类型(通常是结构体)。
MethodName是方法的名称。
parameters是方法接受的参数。
returnList是返回值类型列表。
首先,在utils中定义一个结构体和一个方法:

type Circle struct {
	Radius float64
}

// 定义一个方法,计算圆的面积
// 1. 方法中参数名字随便起
// 2. 方法 Area 和结构体 Circle绑定,必须在同包中定义!
func (c Circle) Area() float64 {
	return 3.14 * c.Radius * c.Radius
}

然后在main中调用:

func main() {
	// 创建一个 Circle 实例
	circle := utils.Circle{Radius: 5}

	// 调用方法
	area := circle.Area()

	// 输出结果
	fmt.Printf("Area: %.2f\n", area)
}

一些细节
1.如果其他类型的变量调用area一定会报错
2.结构体对象传入方法area中,属于值传递,和参数传递一致。
3.receiver的类型是你想要关联的自定义类型
4.如果某个自定义类型实现了返回string,名字为String()的方法(如果是同包内调用,s可以小写),那么fmt包的Printf或Println函数打印该类型时,会自动调用String()
对于前两点,首先,在utils中定义另一个方法来演示值传递:

// 定义一个方法,演示值传递
func (c Circle) SetRadius(newRadius float64) {
	c.Radius = newRadius
	fmt.Printf("Inside Radius: %.2f\n", c.Radius)
}

然后在main文件中调用:

type test struct {
	a int
}

func main() {
	// 创建一个 Circle 实例
	circle := utils.Circle{Radius: 5}

	// 调用方法
	area := circle.Area()
	fmt.Printf("Area: %.2f\n", area)

	// 1. 如果其他类型变量调用 area 一定会报错
	// 下面的代码将导致编译错误
	//t := test{}
	// t.area() // 这行会报错,因为 radius 不是 Circle 类型

	// 2. 结构体对象传入方法 Area 中,属于值传递
	circle2 := utils.Circle{Radius: 10}
	fmt.Printf("Old Radius: %.2f\n", circle2.Radius)

	// 调用 SetRadius 方法尝试修改半径
	circle2.SetRadius(15)
	fmt.Printf("New Radius: %.2f\n", circle2.Radius) // 仍然是 10
}

OK,如果我就想在SetRadius内改变radius呢?那肯定是用指针了,但方法比数组指针简单:将SetRadius中的Circle前加上*即可,因为编译器会自动处理结构体指针,所以在main中的代码无需改动!
对于第三点,receiver的类型是你想要关联的自定义类型,这也就是说,基本类型不能作为方法中的接收类型!读者可自行尝试,这里不做赘述。
对于第四点,首先,在utils内定义String():

func (p Person) String() string {
	str := fmt.Sprintf("name=%s,age=%v,sex=%s", p.Name, p.Age, p.Sex)
	return str
}

然后在main中调用:

func main() {
	p := utils.Person{Name: "李华", Age: 30, Sex: "女"}
	fmt.Printf("%v\n", p) // 使用格式化字符串
	fmt.Println(p)        // 直接打印
}

这个String方法呢,也是定义结构体时常用的,以便输出结构体信息。这里我提一个问题:如果定义了Person的别名,打印其实例还会自动调用String()吗?验证很简单,读者可自行尝试,这里不做赘述。

二、方法与函数的区别

方法函数
和其他类型的关系绑定到特定类型独立于任何类型
语法func (receiver ReceiverType) MethodName(parameters) returnTypefunc FunctionName(parameters) returnType
调用方式通过类型的实例调用 instance.MethodName()直接调用 FunctionName()
作用域可以访问绑定类型的字段只能访问传入的参数
指定类型是否需要和传入类型一致不需要(可以随意传入值或指针)需要

关于最后一点,首先在utils中定义两个接收者不同的方法:

// 方法:接收者为值类型
func (p Person) PValue() {
	fmt.Println("Hello, my name is", p.Name)
}

// 方法:接收者为指针类型
func (p *Person) PPointer() {
	fmt.Println("Hello, my name is", p.Name)
}

然后在main文件中调用:

// 函数:必须传入 Person 类型
func PrintPerson(p utils.Person) {
	fmt.Println("Person's name:", p.Name)
}

func main() {
	// 创建值类型和指针类型的实例
	p1 := utils.Person{Name: "李华"}
	p2 := &utils.Person{Name: "张三"}

	p1.PPointer()   // 调用接收者为指针的方法,传入值类型
	PrintPerson(p1) // 调用函数,传入值类型

	p2.PValue()      // 调用接收者为值类型的方法,传入指针
	PrintPerson(*p2) // 调用函数,传入解引用的指针
}

程序输出如下:

Hello, my name is 李华
Person's name: 李华
Hello, my name is 张三
Person's name: 张三

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JSR303微服务校验

一.创建idea 二.向pom.xml添加依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.7.RELEASE</version></parent><properties><java.vers…

SpringCloud-基于Docker和Docker-Compose的项目部署

一、初始化环境 1. 卸载旧版本 首先&#xff0c;卸载可能已存在的旧版本 Docker。如果您不确定是否安装过&#xff0c;可以直接执行以下命令&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logro…

数字化那点事:一文读懂数字孪生

一、数字孪生的定义 数字孪生&#xff08;Digital Twin&#xff09;是指通过数字技术构建的物理实体的虚拟模型&#xff0c;能够对该实体进行全方位、动态跟踪和仿真预测。简单来说&#xff0c;数字孪生就是在一个设备或系统的基础上创造一个数字版的“克隆体”&#xff0c;这…

【RADARSAT Constellation Mission(RCM)卫星星座简介】

RADARSAT Constellation Mission&#xff08;RCM&#xff09;卫星星座是加拿大太空局&#xff08;CSA&#xff09;的下一代C波段合成孔径雷达&#xff08;SAR&#xff09;卫星星座&#xff0c;以下是对其的详细介绍&#xff1a; 一、基本信息 发射时间&#xff1a;2019年6月…

在Linux系统安装Nginx

注意&#xff1a;Nginx端口号是80(云服务器要放行) 我的是基于yum源安装 安装yum源(下面这4步就好了) YUM源 1、将源文件备份 cd /etc/yum.repos.d/ && mkdir backup && mv *repo backup/ 2、下载阿里源文件 curl -o /etc/yum.repos.d/CentOS-Base.repo ht…

Adobe PR与AE的区别与联系(附网盘地址)

从事视频后期制作的小伙伴&#xff0c;对于PR&#xff08;Premiere&#xff09;和AE&#xff08;After Effects&#xff09;应该不会陌生。随着短视频的兴起&#xff0c;就连我们普通用户&#xff0c;拍摄完视频&#xff0c;都会去糟取精的剪辑一下&#xff0c;而PR正是一款功能…

【分布式微服务云原生】windows+docker+mysql5.7.44一主一从主从复制

目录 1. 主库设置2. 从库设置3. 验证主从复制内容汇总表格 摘要&#xff1a; 在Windows系统上通过Docker部署MySQL主从复制&#xff0c;以下是详细的步骤和命令&#xff0c;帮助你设置一主一从的MySQL复制环境。 1. 主库设置 步骤1&#xff1a;运行MySQL主库容器 docker run …

探索Python网络世界的利器:Requests-HTML库

文章目录 探索Python网络世界的利器&#xff1a;Requests-HTML库背景&#xff1a;为何选择Requests-HTML&#xff1f;什么是Requests-HTML&#xff1f;如何安装Requests-HTML&#xff1f;5个简单库函数的使用方法3个场景下库的使用示例常见Bug及解决方案总结 探索Python网络世界…

微服务nginx解析部署使用全流程

目录 1、nginx介绍 1、简介 2、反向代理 3、负载均衡 2、安装nginx 1、下载nginx 2、解压nginx安装包 3、安装nginx​编辑 1、执行configure命令 2、执行make命令 4、启动nginx 1、查找nginx位置并启动 2、常用命令 3、反向代理 1、介绍反向代理配置 1、基础配置…

【iOS】计算器的仿写

计算器 文章目录 计算器前言简单的四则运算UI界面事件的逻辑小结 前言 笔者应组内要求&#xff0c;简单实现了一个可以完成简单四则运算的计算器程序。UI界面则是通过最近学习的Masonry库来实现的&#xff0c;而简单的四则运算内容则是通过栈来实现一个简单的四则运算。 简单…

Halcon实用系列1-识别二维条码

在做项目时&#xff0c;之前使用的是某康的智能读码器&#xff0c;综合考虑成本&#xff0c;可通过相机拍照来读取图片的二维码&#xff0c;我这边用Halcon来实现。 Halcon代码如下&#xff1a; *创建模型 create_data_code_2d_model(Data Matrix ECC 200, [], [], DataCodeH…

5G NR物理信道简介

文章目录 NR 上行物理信道PRACHPUCCHPUSCH NR 下行物理信道PBCHPDCCHPDSCH NR 上行物理信道 PRACH PRACH&#xff08;Physical Random Access Channel)物理随机接入信道&#xff0c;用于传导preamble 序列。PRACH 由循环前缀CP、前导序列和保护间隔三部分组成。 PUCCH PUCCH…

【AI大模型】深入Transformer架构:编码器部分的实现与解析(上)

目录 &#x1f354; 编码器介绍 &#x1f354; 掩码张量 2.1 掩码张量介绍 2.2 掩码张量的作用 2.3 生成掩码张量的代码分析 2.4 掩码张量的可视化 2.5 掩码张量总结 &#x1f354; 注意力机制 3.1 注意力计算规则的代码分析 3.2 带有mask的输入参数&#xff1a; 3.…

FOCShield v2.0.4原理图

1.FOCShield v2.0.4原理图,开源原文件用AD制作。用 AD09可以打开。 主要部分为 1.电机驱动芯片部分 2.电流采样部分

Windows 环境下安装 Anaconda 并适配到 PowerShell 的保姆级教程

Anaconda Anaconda 是一个流行的 Python 数据科学和机器学习平台&#xff0c;它包括了 Conda 包管理器、Python 以及数百个用于科学计算的库和工具。Anaconda 旨在简化包和环境管理&#xff0c;使得安装、更新和管理软件包变得容易&#xff0c;同时也能够轻松创建和切换不同的P…

大数据毕业设计选题推荐-民族服饰数据分析系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【Linux】命令管道

一、命名管道的介绍 之前的管道博客中介绍的是匿名管道&#xff0c;这个管道的应用的一个限制就是只能在具有公共祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。 如果我们不想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件来做这项工作&#xff0c;他经常…

输入捕获模式测频率PWMI模式测频率占空比

前沿知识&#xff1a;TIM输入捕获-CSDN博客 输入捕获相关函数 // 初始化输入捕获单元 // ICInit是4个通道共用一个函数的&#xff0c;第二个结构体参数&#xff0c;可以用来配置具体是哪个通道。 void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);/…

【MAUI】CollectionView之 垂直网格

App主页或者导航页面中动态按钮的垂直网格布局 在 XAML 中,CollectionView 可以通过将其 ItemsLayout 属性设置为 VerticalGrid,在垂直网格中显示其项: <CollectionView ItemsSource="{Binding Monkeys}"ItemsLayout

TCP/UDP初识

TCP是面向连接的、可靠的、基于字节流的传输层协议。 面向连接&#xff1a;一定是一对一连接&#xff0c;不能像 UDP 协议可以一个主机同时向多个主机发送消息 可靠的&#xff1a;无论的网络链路中出现了怎样的链路变化&#xff0c;TCP 都可以保证一个报文一定能够到达接收端…