当前位置: 首页 > news >正文

深入理解Go语言的方法定义与使用

在Go语言编程中,方法(Method) 是附属于特定类型的函数,使我们能够以面向对象的方式编写代码。通过方法,我们可以更自然地对类型进行操作。本文将通过实际的代码示例,深入探讨Go语言中方法的定义与使用。

一、准备工作

为了实践本文的内容,我们需要先创建一个新的Go项目。

1. 创建项目目录

打开命令行,导航到合适的目录下,创建一个名为methodsAndInterfaces的文件夹:

mkdir methodsAndInterfaces
cd methodsAndInterfaces

2. 初始化Go模块

methodsAndInterfaces目录下,运行以下命令初始化Go模块:

go mod init methodsandinterfaces

3. 创建main.go文件

methodsAndInterfaces目录下,创建一个名为main.go的文件,输入以下内容:

package mainimport "fmt"// 定义Product结构体
type Product struct {name, category stringprice          float64
}func main() {// 创建Product指针的切片products := []*Product{{"皮划艇", "水上运动", 275},{"救生衣", "水上运动", 48.95},{"足球", "足球运动", 19.50},}// 遍历并打印商品信息for _, p := range products {fmt.Println("名称:", p.name, "分类:", p.category, "价格:", p.price)}
}

4. 运行程序

在命令行中,确保当前目录是methodsAndInterfaces,运行以下命令:

go run .

程序将输出:

名称: 皮划艇 分类: 水上运动 价格: 275
名称: 救生衣 分类: 水上运动 价格: 48.95
名称: 足球 分类: 足球运动 价格: 19.5

二、定义和使用方法

1. 从函数到方法

首先,我们来看一个普通的函数如何定义:

// 定义一个函数,接收*Product类型的参数
func printDetails(product *Product) {fmt.Println("名称:", product.name, "分类:", product.category, "价格:", product.price)
}

main函数中,我们可以这样调用它:

for _, p := range products {printDetails(p) // 调用函数
}

2. 将函数转换为方法

现在,我们将上述函数转换为Product类型的方法:

// 定义一个方法,作用于*Product类型
func (product *Product) printDetails() {fmt.Println("名称:", product.name, "分类:", product.category, "价格:", product.price)
}

注意这里的(product *Product)部分,这就是方法的接收者,表示printDetails方法绑定到了*Product类型。

main函数中,调用方法的方式也有所不同:

for _, p := range products {p.printDetails() // 调用方法
}

这样,我们就将函数转换为了方法,调用时更加直观。

三、方法的参数和返回值

方法可以像函数一样,拥有自己的参数和返回值。

1. 定义带参数和返回值的方法

我们为Product类型定义一个计算税后价格的方法:

// 计算税后价格的方法
func (product *Product) calcTax(rate, threshold float64) float64 {if product.price > threshold {return product.price + (product.price * rate)}return product.price
}
  • rate:税率
  • threshold:价格阈值,超过该值才计算税

2. 在方法中调用另一个方法

修改printDetails方法,调用calcTax方法:

func (product *Product) printDetails() {finalPrice := product.calcTax(0.2, 100) // 计算税后价格fmt.Println("名称:", product.name, "分类:", product.category, "价格:", finalPrice)
}

3. 运行结果

重新运行程序,输出如下:

名称: 皮划艇 分类: 水上运动 价格: 330
名称: 救生衣 分类: 水上运动 价格: 48.95
名称: 足球 分类: 足球运动 价格: 19.5

可以看到,价格高于100的商品(皮划艇)被加上了20%的税费。

四、方法重载的限制

1. Go语言不支持方法重载

在Go语言中,不支持方法重载。也就是说,不能在同一个类型上定义多个同名的方法,即使它们的参数不同。

2. 示例

如果尝试这样做:

func (product *Product) printDetails() {// 方法体
}func (product *Product) printDetails(showPrice bool) {// 方法体
}

编译器会报错:

method redeclared: Product.printDetails

3. 合理命名方法

为了避免冲突,应为不同的方法使用不同的名称,例如printBasicDetailsprintFullDetails

五、指针接收者和值接收者

1. 指针接收者

当方法的接收者是指针类型时,可以通过值类型指针类型的变量调用该方法,Go会自动完成转换。

func (product *Product) printDetails() {// 方法体
}func main() {prod := Product{"皮划艇", "水上运动", 275}prod.printDetails() // 自动转换为指针类型调用
}

2. 值接收者

同样,当方法的接收者是值类型时,也可以通过指针类型的变量调用。

func (product Product) showCategory() {fmt.Println("分类:", product.category)
}func main() {prodPtr := &Product{"救生衣", "水上运动", 48.95}prodPtr.showCategory() // 自动解引用,调用值接收者的方法
}

3. 选择接收者类型

  • 指针接收者:需要修改接收者,或者接收者包含大量数据,避免拷贝。
  • 值接收者:接收者为基本类型,方法不需要修改接收者状态。

六、为类型别名定义方法

1. 定义类型别名

我们可以使用type关键字为现有类型创建别名,然后为其定义方法。

// 定义ProductList类型,表示Product的切片
type ProductList []Product

2. 为类型别名定义方法

// 计算各分类商品总价的方法
func (products ProductList) calcCategoryTotals() map[string]float64 {totals := make(map[string]float64)for _, p := range products {totals[p.category] += p.price}return totals
}

3. 使用方法

func main() {products := ProductList{{"皮划艇", "水上运动", 275},{"救生衣", "水上运动", 48.95},{"足球", "足球运动", 19.50},}totals := products.calcCategoryTotals()for category, total := range totals {fmt.Println("分类:", category, "总价:", total)}
}

4. 运行结果

分类: 水上运动 总价: 323.95
分类: 足球运动 总价: 19.5

七、将类型和方法分离到不同文件

1. 项目结构的优化

随着项目的增长,将所有代码写在一个文件中会使得代码难以维护。我们可以将类型和方法分离到不同的文件中,但它们需要属于同一个包。

2. 创建product.go文件

package main// 定义Product结构体
type Product struct {name, category stringprice          float64
}// 为Product定义方法
func (product *Product) printDetails() {fmt.Println("名称:", product.name, "分类:", product.category, "价格:", product.price)
}

3. 创建service.go文件

package main// 定义Service结构体
type Service struct {description    stringdurationMonths intmonthlyFee     float64
}// 为Service定义方法
func (service *Service) printDetails() {totalFee := service.monthlyFee * float64(service.durationMonths)fmt.Println("服务:", service.description, "总费用:", totalFee)
}

4. 修改main.go文件

package mainfunc main() {product := Product{"皮划艇", "水上运动", 275}service := Service{"船只保险", 12, 89.50}product.printDetails()service.printDetails()
}

5. 运行结果

名称: 皮划艇 分类: 水上运动 价格: 275
服务: 船只保险 总费用: 1074

通过将代码拆分到不同的文件中,我们的项目结构更加清晰,代码维护也更方便。

八、总结与补充

本文详细介绍了Go语言中方法的定义和使用,包括:

  • 将函数转换为方法
  • 方法的参数和返回值
  • 方法重载的限制
  • 指针接收者和值接收者
  • 为类型别名定义方法
  • 将类型和方法分离到不同文件

相关文章:

深入理解Go语言的方法定义与使用

在Go语言编程中,方法(Method) 是附属于特定类型的函数,使我们能够以面向对象的方式编写代码。通过方法,我们可以更自然地对类型进行操作。本文将通过实际的代码示例,深入探讨Go语言中方法的定义与使用。 一…...

堆排序,快速排序

目录 1.堆排序 2.快速排序 1.hoare版本 2.挖坑法 3.前后指针法 注意点 1.堆排序 void Swap(int* a, int* b) {int tmp *a;*a *b;*b tmp; } void adjustdown(int* a, int n, int parent) {int child parent * 2 1;while (child < n){if (child 1 < n &&am…...

系统架构师---数据库设计的四个阶段

需求分析、概念设计、逻辑设计和物理设计是数据库设计中的四个关键阶段&#xff0c;每个阶段都有其独特的任务和目标&#xff0c;以下是对这四个阶段的区别的详细阐述&#xff1a; 需求分析阶段 目标&#xff1a;全面理解用户对数据库系统的需求&#xff0c;包括业务需求、信…...

MySQL_简介及安装、配置、卸载(超详细)

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…...

大数据处理技术:分布式文件系统HDFS

目录 1 实验名称&#xff1a; 2 实验目的 3 实验内容 4 实验原理 5 实验过程或源代码 5.1 HDFS的基本操作 5.2 HDFS-JAVA接口之读取文件 5.3 HDFS-JAVA接口之上传文件 5.4 HDFS-JAVA接口之删除文件 6 实验结果 6.1 HDFS的基本操作 6.2 HDFS-JAVA接口之读取文件 6.…...

组合数(模板)

1.杨辉三角求组合数&#xff0c;最高只能求几千内的组合数。 #include<bits/stdc.h> using namespace std; #define int long long int C[1005][1005]; signed main() {//求 1000 以内的组合数 for(int i0;i<1000;i){C[i][0]C[i][i]1;for(int j1;j<i;j){C[i][j]C[…...

时序数据库 TDengine 的入门体验和操作记录

时序数据库 TDengine 的学习和使用经验 什么是 TDengine &#xff1f;什么是时序数据 &#xff1f;使用RPM安装包部署默认的网络端口 TDengine 使用TDengine 命令行&#xff08;CLI&#xff09;taosBenchmark服务器内存需求删库跑路测试 使用体验文档纠错 什么是 TDengine &…...

Qt-QPushButton按钮类控件(22)

目录 描述 使用 给按钮添加图片 给按钮添加快捷键 添加槽函数 添加快捷键 添加组合键 开启鼠标的连发功能 描述 经过上面的一些介绍&#xff0c;我们也尝试的使用过了这个控件&#xff0c;接下来我们就要详细介绍这些比较重要的控件了 使用 给按钮添加图片 我们创建…...

镜舟科技与中启乘数科技达成战略合作,共筑数据服务新生态

当今企业数据管理日益规范化&#xff0c;数据应用系统随着数据类型与数量的增长不断细分&#xff0c;为了提升市场竞争力与技术实力&#xff0c;数据领域软件服务商与上下游伙伴的紧密对接与合作显得尤为重要。通过构建完善的生态系统&#xff0c;生态内企业间能够整合资源、共…...

蒸!--数据在内存中的存储

一.整数在内存中的存储 对于整形来说&#xff1a;数据存放内存中其实存放的是补码。 为什么&#xff1f; 在计算机系统中&#xff0c;数值⼀律⽤补码来表⽰和存储。 原因在于&#xff0c;使⽤补码&#xff0c;可以将符号位和数值域统⼀处理&#xff1b; 同时&#xff0c;加法和…...

利用AI增强现实开发:基于CoreML的深度学习图像场景识别实战教程

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…...

每个企业都需要 (但未使用) 的 BYOD 安全解决方案

远程办公模式的转变彻底改变了组织管理员工设备的方式。如今&#xff0c;员工希望能够灵活地在任何地方使用任何设备工作&#xff0c;这导致自带设备 (BYOD) 政策被广泛采用。 但随着越来越多的企业采用BYOD&#xff0c;一个问题依然摆在眼前&#xff1a;如何在不侵犯个人隐私…...

【多系统萎缩患者必看】科学锻炼秘籍,让生命之树常青

亲爱的小红书朋友们&#xff0c;&#x1f44b; 今天我们要聊一个温暖而坚韧的话题——关于多系统萎缩&#xff08;MSA&#xff09;患者的锻炼指南。在这个充满挑战的旅程中&#xff0c;锻炼不仅是身体的锻炼&#xff0c;更是心灵的滋养&#xff0c;是对抗病魔的勇敢姿态&#x…...

【Android】Room—数据库的基本操作

引言 在Android开发中&#xff0c;数据持久化是一个不可或缺的部分。随着应用的复杂度增加&#xff0c;选择合适的数据存储方式变得尤为重要。Room数据库作为Android Jetpack架构组件之一&#xff0c;提供了一种抽象层&#xff0c;使得开发者能够以更简洁、更安全的方式操作SQ…...

「数组」堆排序 / 大根堆优化(C++)

目录 概述 核心概念&#xff1a;堆 堆结构 数组存堆 思路 算法过程 up() down() Code 优化方案 大根堆优化 Code(pro) 复杂度 总结 概述 在「数组」快速排序 / 随机值优化|小区间插入优化&#xff08;C&#xff09;中&#xff0c;我们介绍了三种基本排序中的冒泡…...

Edegex Foundry docker和源码安装

edgex文档下载 https://github.com/edgexfoundry/edgex-docs/branches/all 在线文档查看 首先要安装python3环境 然后后安装 打开超级终端 #pip3 install mkdocs #mkdocs serve 在浏览器中输入 http://127.0.0.1:8000/edgex-docs/2.3/ 即可打开在线文档 edgex入门可以参考…...

阿里P8和P9级别有何要求

阿里巴巴的P8和P9级别&#xff0c;代表着公司的资深技术专家或管理者岗位&#xff0c;要求候选人具有丰富的职业经历、深厚的技术能力以及出色的领导力。以下是对P8和P9级别的要求、考察点以及准备建议的详细分析。 P8 级别要求 1. 职业经历&#xff1a; 8年以上的工作经验&a…...

【目标检测数据集】锯子数据集1107张VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1107 标注数量(xml文件个数)&#xff1a;1107 标注数量(txt文件个数)&#xff1a;1107 标注…...

移动产业处理器接口(MIPI)协议是什么?

未来汽车的宏伟愿景备受瞩目&#xff0c;特别是驱动这些汽车的技术更是成为焦点。如今&#xff0c;传感器对于汽车视觉和安全技术的下一阶段至关重要&#xff0c;因为驾驶员和乘客都依赖于它们。这些传感器能够支持众多应用&#xff0c;这些应用往往基于人工智能&#xff08;AI…...

OpenAI o1:隐含在训练与推理间的动态泛化与流形分布

随着OpenAI o1发布&#xff0c;进一步激发了产业与学术各界对AGI的期待以及new scaling law下的探索热情&#xff0c;也看到来自社区和专业机构对o1的阐释&#xff0c;但总感觉还差点什么&#xff0c;因此决定以自己的角度分篇幅梳理下&#xff0c;并分享给大伙&#xff1a; O…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...