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

news2024/9/30 7:32:43

本节内容是面向对象的核心与基础,很重要。
注意:由于导包语句已经在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.coloradmin.cn/o/2179058.html

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

相关文章

《程序猿之Redis缓存实战 · Redis 与数据库一致性》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…

多模态人像编辑:PortraitGen将2D肖像视频提升到4D 高斯场

这篇文章《Portrait Video Editing Empowered by Multimodal Generative Priors》,作者是来自中国科学技术大学。文章介绍了一种名为PortraitGen的肖像视频编辑方法,它使用多模态生成先验来实现一致性和富有表现力的风格化编辑。 文章地址:P…

electron教程(三)窗口设置

在main.js文件中,创建窗口时会设置窗口的大小,其实还有很多其他属性,可以根据实际需求选择设置,但部分属性存在局限性,官网也有明确告知:自定义窗口 | Electron (electronjs.org) 项目文件目录如下&#x…

6.1 微服务 服务发现 架构模式分类 应用实践

微服务 服务发现 架构模式分类 应用实践 目录概述需求: 设计思路实现思路分析1.类型-客户端发现2.类型-服务端服务发现3.工具-Eureka4.工具-Consul5.工具-zookper服务发现的挑战服务发现的最佳实践 参考资料和推荐阅读 Survive by day and develop by night. talk …

【三步 完全离线搭建 openwebui 】

完全离线linux 版open webui 的搭建 1.在具有网络连接的环境中下载whl 在有网络的环境&#xff0c;使用pip download可以保存所有的依赖包,可以使用-i 指定清华的镜像源加速下载速度。 # 命令&#xff1a; pip download <package_name> --only-binary:all: --wheel --…

CANoe_DBC能够打开但是无法使用“BusType”

解决DBC文件在CAPL中调用问题&#xff1a;从CANdb到CAPL的顺畅过渡 在汽车电子和嵌入式系统开发中&#xff0c;DBC&#xff08;Database CAN&#xff09;文件作为描述CAN&#xff08;Controller Area Network&#xff09;通信协议的重要工具&#xff0c;广泛应用于网络设计、测…

前端考核总结

目录 JavaScript的基本数据类型有哪些&#xff1f;JavaScript中数据类型的检测方法JavaScript如何判断对象中的属性存在自身还是原型链上flex布局HTML5新标签Vue的基本概念Vue生命周期JavaScript中闭包的基本概念防抖节流双等号与三等号的区别显式转换 JavaScript的基本数据类型…

Flume实战--Flume中的选择器、自动容灾(故障转移)、负载均衡的详解与操作

本文详细介绍了Apache Flume的关键特性&#xff0c;包括选择器、拦截器、故障转移和负载均衡。选择器负责将数据分发到多个Channel&#xff0c;拦截器用于修改或丢弃Event。故障转移机制能够在Sink故障时自动切换&#xff0c;而负载均衡则在多个Sink间分配负载。文章还提供了自…

【零基础入门产品经理】学习准备篇 | 需要学一些什么呢?

前言&#xff1a; 零实习转行产品经理经验分享01-学习准备篇_哔哩哔哩_bilibili 该篇内容主要是对bilibili这个视频的观后笔记~谢谢美丽滴up主友情分享。 全文摘要&#xff1a;如何在0实习且没有任何产品相关经验下&#xff0c;如何上岸产品经理~ 目录 一、想清楚为什么…

Redis 基础数据改造

优质博文&#xff1a;IT-BLOG-CN 一、服务背景 基础数据查询服务&#xff1a;提供航司、机场、票台、城市等基础数据信息。 痛点一&#xff1a;因为基础数据不属于频繁更新的数据&#xff0c;所以每个应用都有自己和缓存&#xff0c;当基础数据更新后&#xff0c;各个应用缓存…

webGL入门(五)绘制多边形

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><scri…

ARM 服务器上安装 OpenEuler (欧拉)

系统介绍 在 2019 年 7 月 19 日&#xff0c;华为宣布要在年底正式开源 openEuler 操作系统&#xff1b;在半年后的 12 月 31 日&#xff0c;华为正式开源了 openEuler 操作系统&#xff0c;邀请社区开发者共同来贡献。 一年后&#xff0c;截止到 2020 年12 月 25日&#xff…

计算机毕业设计 Java教务管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

[Cocoa]_[初级]_[使用NSNotificationCenter作为目标观察者实现时需要注意的事项]

场景 在开发Cocoa程序时&#xff0c;由于界面是用Objective-C写的。无法使用C的目标观察者[1]类。如果是使用第二种方案2[2],那么也需要增加一个代理类。那么有没有更省事的办法&#xff1f; 说明 开发界面的时候&#xff0c;经常是需要在子界面里传递数据给主界面&#xff0…

PIKACHU | PIKACHU 靶场 XSS 后台配置

关注这个靶场的其他相关笔记&#xff1a;PIKACHU —— 靶场笔记合集-CSDN博客 PIKACHU 自带了一个 XSS 平台&#xff0c;可以辅助我们完成 XSS 攻击&#xff0c;但是该后台需要配置数据库以后才能使用。本教程&#xff0c;就是教大家如何配置 PIKACHU XSS 平台的。 PIKACHU XS…

vulhub weblogic 靶场攻略

一&#xff1a;WebLogic 后台弱⼝令GetShell&#xff08;weak_password &#xff09; 漏洞描述 通过弱⼝令进⼊后台界⾯ , 上传部署war包 , getshell 影响范围 全版本&#xff08;前提后台存在弱⼝令&#xff09; 环境搭建 cd vulhub-master/weblogic/weak_password doc…

【STM32开发环境搭建】-4-在STM32CubeMX中新增Keil(MDK-ARM) 5的工程目录(包含指定路径的C和H文件)

案例背景&#xff1a; 由于Keil(MDK-ARM)5工程&#xff1a;DEMO_STM32F030C8T6.uvprojx是由STM32CubeMX工具生成的&#xff0c;如果我们在Keil工程中手动添加了一些c文件和h文件的Include Path包含路径&#xff0c;会在STM32CubeMX下一次生成uvprojx文件时&#xff0c;被删除&…

纯软件小白 学习DDR5

问题 1.你知道当你打开游戏加载存档时候计算机是在做什么吗&#xff1f; 由于你的CPU只有在数据被加载到DRAM的时候才可以工作&#xff0c;所以当你需要用数据的时候&#xff0c;数据会从SSD复制到DRAM这一过程需要时间&#xff0c;所以会有加载&#xff08;所有3D模型、纹理…

【从零开始实现stm32无刷电机FOC】【实践】【7.1/7 硬件设计】

目录 stm32电路磁编码器电路电机驱动电路电流采样电路电机选择本文示例硬件说明 为了承载和验证本文的FOC代码工程&#xff0c;本节设计了一个简易的三相无刷电机 硬件套件&#xff0c;主控采用非常常用的stm32f103c8t6单片机&#xff0c;电机编码器采用MT6701&#xff0c;电机…

电源的带载能力怎么判断?Namisoft为您介绍测试方法

确保电源在各种负载条件下都能稳定工作&#xff0c;是电源设计者面临的重要挑战。本文将详细介绍如何通过带载测试来评估电源的负载能力。 电源带载测试介绍 带载能力指电源在其规定条件下&#xff0c;所能承受的最大负载能力。电源带载测试就是对电源模块的负载能力进行测试&a…