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

Golang学习笔记_17——方法

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

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

4. 调用

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

type Person struct {
	Name string
	Age  int
}

func (p Person) SayHello() {
	fmt.Printf("%s say: Hello\n\n", p.Name)
}

func (p *Person) addAge() {
	p.Age = p.Age + 1
	fmt.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_demo

import "fmt"

type Person struct {
	Name string
	Age  int
}

func (p Person) SayHello() {
	fmt.Printf("%s say: Hello\n\n", p.Name)
}

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

// method_demo_test.go 文件
package method_demo

import "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.kler.cn/a/472438.html

相关文章:

  • 【C++】B2106 矩阵转置
  • B树及其Java实现详解
  • 如何使用进度条来显示QFle读取文件进度
  • mysql -> 达梦数据迁移(mbp大小写问题兼容)
  • 深入学习RabbitMQ的Direct Exchange(直连交换机)
  • 【OJ刷题】同向双指针问题
  • 【Leetcode】单词拆分:dfs解法、dp解法
  • 计算机网络之---物理层的基本概念
  • 大数据hadoop和hive能支持多大
  • Linux性能优化策略:让你的系统运行如飞
  • Boost.Asio 的 TCP 通信教程
  • Redis 渐进式遍历与数据库管理
  • UE5AI感知组件
  • 用CLEAN算法实现杂波抑制的Matlab仿真程序
  • 《深度学习模型在鸿蒙分布式框架下的跨设备高效之旅》
  • Tauri教程-基础篇-第二节 Tauri的核心概念上篇
  • .NET中的框架和运行环境
  • Vue.js组件开发-如何避免props中的数据冲突
  • 面试手撕-多线程死锁
  • 升级 Spring Boot 3 配置讲解 —— 为何 SpringBoot3 淘汰了 JDK8?
  • 探索大型语言模型新架构:从 MoE 到 MoA
  • 浙江生易达自控科技:品质与实力的象征
  • idea 远程docker 本地需要安装docker吗
  • 阿里云代理商热销产品推荐
  • 05-Linux系统编程之进程(下)
  • Transformer深度学习实战TT100K中国交通标志识别