Golang学习笔记_17——方法

news/2025/1/8 15:06:55/

Golang学习笔记_14——切片
Golang学习笔记_15——range
Golang学习笔记_16——Map


文章目录

    • 方法
      • 1. 介绍
      • 2. 定义
      • 3. 值接收者和指针接收者
      • 4. 调用
      • 5. 用途
      • 6. 方法与函数的区别
      • 7. 建议选择指针作为接收者
    • 源码


方法

Go 没有类。不过你可以为类型定义方法。

方法就是一类带特殊的 接收者 参数的函数。

方法接收者在它自己的参数列表内,位于 func 关键字和方法名之间。

1. 介绍

在Go语言中,方法(Method)是一种带有接收者(Receiver)的函数。

接收者可以是值接收者(Value Receiver)或指针接收者(Pointer Receiver),并且它允许我们为特定类型定义附加的行为。

方法使得我们可以像面向对象编程一样为结构体(Struct)或其他类型定义方法,但Go本身并不是纯面向对象的语言。

记住:方法只是个带接收者参数的函数。

2. 定义

func (recv ReceiverType) MethodName(parameters) (results) {// 方法体
}
  • recv:接收者变量名,它是方法作用的对象实例。
  • ReceiverType:接收者的类型,可以是值类型或指针类型。
  • MethodName:方法的名称。
  • parameters:方法的参数列表。
  • results:方法的返回值列表。

3. 值接收者和指针接收者

  • 值接收者:如果方法使用值接收者,那么在方法内部对接收者所做的修改不会影响原始数据。

    type Person struct {Name stringAge  int
    }func (p Person) Greet() {fmt.Println("Hello, my name is", p.Name)
    }
    
  • 指针接收者:如果方法使用指针接收者,那么在方法内部对接收者所做的修改会影响原始数据。通常,如果方法需要修改接收者的状态,应该使用指针接收者。

    func (p *Person) HaveBirthday() {p.Age++
    }
    

4. 调用

调用方法与调用普通函数类似,但方法是通过接收者实例来调用的

type Person struct {Name stringAge  int
}func (p Person) SayHello() {fmt.Printf("%s say: Hello\n\n", p.Name)
}func (p *Person) addAge() {p.Age = p.Age + 1fmt.Printf("%s say: Added age to the new age: %d\n", p.Name, p.Age)
}

测试方法

func TestPerson_SayHello(t *testing.T) {bob := Person{"Bob", 20}bob.SayHello()
}func TestPerson_addAge(t *testing.T) {tom := Person{"Tom", 30}tom.addAge()
}

输出结果

=== RUN   TestPerson_addAge
Tom say: Added age to the new age: 31
--- PASS: TestPerson_addAge (0.00s)
PASS

5. 用途

  • 封装行为:将特定类型的操作封装在方法内部,使得代码更加模块化。
  • 数据抽象:通过方法隐藏数据结构的实现细节,只暴露必要的接口。
  • 多态:通过接口(Interface)和方法,可以实现Go语言中的多态特性。

6. 方法与函数的区别

  • 方法是带接收者的函数,而普通函数则没有接收者。
  • 方法是通过类型实例调用的,而函数则是直接通过包名或变量名调用的。
  • 带指针参数的函数必须接受一个指针,接受一个值作为参数的函数必须接受一个指定类型的值
  • 接收者为指针的的方法被调用时,接收者既能是值又能是指针
    • 带指针的接收者被值直接调用时,Go会将值解释为指针。
  • 以值为接收者的方法被调用时,接收者既能为值又能为指针
    • 带值的接收者被指针调用时,Go会降指针解释为值

7. 建议选择指针作为接收者

  1. 方法能够修改其接收者指向的值。
  2. 这样可以避免在每次调用方法时复制该值。若值的类型为大型结构体时,这样会更加高效。

源码

// method_demo.go 文件
package method_demoimport "fmt"type Person struct {Name stringAge  int
}func (p Person) SayHello() {fmt.Printf("%s say: Hello\n\n", p.Name)
}func (p *Person) addAge() {p.Age = p.Age + 1fmt.Printf("%s say: Added age to the new age: %d\n", p.Name, p.Age)
}
// method_demo_test.go 文件
package method_demoimport "testing"func TestPerson_SayHello(t *testing.T) {bob := Person{"Bob", 20}bob.SayHello()
}func TestPerson_addAge(t *testing.T) {tom := Person{"Tom", 30}tom.addAge()
}

http://www.ppmy.cn/news/1561260.html

相关文章

gesp(C++四级)(3)洛谷:B3850:[GESP202306 四级] 幸运数

gesp(C四级)(3)洛谷:B3850:[GESP202306 四级] 幸运数 题目描述 小明发明了一种 “幸运数”。一个正整数,其偶数位不变(个位为第 1 1 1 位,十位为第 2 2 2 位,以此类推&#xff09…

Excel-vlookup 函数使用

3个函数: 1. vlookup函数,对应查找 2.column函数,计算列 3.countif函数,查找总数 4.concat函数,连接。 一、简单vlookup,查找值只出现一次 VLOOKUP(B2,F:G,2,FALSE) B2,查找值,…

学习笔记 --C#基础其他知识点(数据结构)

C#中的数据结构《二》–视频学习笔记 在数据结构的分类: 1.集合 2.线性 3.树形 4.图状结构 数据结构是数据在程序中的存储结构,和基本的数据操作 算法:解决问题的解决思路,基于数据结构 本课程包括:线性表&#xff…

条款47:请使用 traits classes 表现类型信息(Use traits classes for information about types)

条款47&#xff1a;请使用 traits classes 表现类型信息 1.1 提出问题 想一想&#xff0c;下面的功能如何实现&#xff1f;&#xff08;可以查看std::advance源码&#xff09; template<typename IterT, typename DistT> void advance(IterT& iter, DistT d); /…

游戏引擎学习第74天

仓库: https://gitee.com/mrxiao_com/2d_game (仓库满了) gitee 好像一个仓库最多1G https://gitee.com/mrxiao_com/2d_game_2 后面改到https://gitee.com/mrxiao_com/2d_game_2 仓库 代码占的内存不大主要是markdown截图700多兆比较占内存 Blackboard: 以对处理实体对的方式进…

代码随想录 day62 第十一章 图论part11

第十一章&#xff1a;图论part11 Floyd 算法精讲 Floyd 算法代码很简单&#xff0c;但真正理解起原理 还是需要花点功夫&#xff0c;大家在看代码的时候&#xff0c;会发现 Floyd 的代码很简单&#xff0c;甚至看一眼就背下来了&#xff0c;但我为了讲清楚原理&#xff0c;本…

SQL 实现复杂地理围栏 – 多边形区域判断与距离筛选

在位置服务、物流配送、LBS&#xff08;基于位置的服务&#xff09;等场景中&#xff0c;地理围栏&#xff08;Geofence&#xff09;是一个重要功能。通过 SQL 查询&#xff0c;我们可以借助空间索引和地理函数&#xff0c;精准判断目标是否在多边形区域内&#xff0c;或计算两…

同步与并发:Java的同步舞蹈

现在&#xff0c;我们将深入探讨同步与并发&#xff0c;这是确保多线程程序正确性和效率的关键&#xff0c;就像是Java的同步舞蹈。 1 并发的概念 并发是指在多处理器系统中&#xff0c;多个操作或多个线程同时进行执行。在Java中&#xff0c;这意味着能够有效地利用多核处理…