golang中关于map的value类型定义为函数类型时(方法值)的一点点思考
文章的内容仅仅是自己关于map的value类型定义为函数类型时的一点点思考,如有不对的地方,请不吝赐教。
学习过后才知道叫做 方法值。
1、起因
最近在看老项目代码时,看到了一段类似于下面的定义,最开始看到的时候,对于 LotMap 的用法比较疑惑,为什么 map value 定义的函数类型是 func(r *Receiver, lot *Lot, msg *History)
,但是在初始化时,传递的值却是(*Receiver).handleStart
。
然后根据自己的有了下面的思考,如有不对,请多指教。
package main
var LotMap = map[string]func(r *Receiver, lot *Lot, msg *History){
"start": (*Receiver).handleStart,
"end": (*Receiver).handleEnd,
}
type Lot struct {
}
type History struct {
}
type Receiver struct{}
func (r *Receiver) handleStart(lot *Lot, msg *History) {
}
func (r *Receiver) handleEnd(lot *Lot, msg *History) {
}
func main() {
r := &Receiver{}
lot := &Lot{}
msg := &History{}
LotMap["start"](r, lot, msg)
}
2、原因
如果你有我一样的疑惑,接下来我们一起看看是为啥?
《go 语言圣经》中的第6.4. 方法值和方法表达式 有讲解关于方法值的介绍。
大家可以先去看看原文关于方法值的介绍后,再来看本文。
说实话,我看了上面的文章中的介绍后,对于方法值还是一头雾水,不知道在讲什么。(怪我太菜)
接下来我按照自己的理解,说说对于方法值的理解。
2.1、什么叫方法值
在Go语言中,方法值(method value)指的是将方法绑定到特定接收者实例上,从而创建一个函数值(function value)
。方法值允许你将方法视为普通函数,可以将其传递给其他函数或者存储在变量中,之后在不同的上下文中调用。
例如,如果有一个方法 func (r *Receiver) handleStart(lot *Lot, msg *History)
,你可以使用 (*Receiver).handleStart
创建一个方法值,然后将其传递给其他函数或存储在变量中,如下所示:
// 方法值的创建
methodValue := (*Receiver).handleStart
// 将方法值传递给其他函数
someFunction(methodValue)
// 存储方法值到变量中
var myFunction func(r *Receiver, lot *Lot, msg *History)
myFunction = methodValue
在这里,methodValue
就是一个方法值,它与特定的接收者实例无关,可以在任何需要的地方使用,类似于普通的函数值。
2.2、 样例解释
看完了上面的的 何为方法值后,相比应该对方法值有一定的了解,对于样例的用法,也熟悉了不少。
接下里,我们在 main 函数中加入下面的语句
func main() {
r := &Receiver{}
lot := &Lot{}
msg := &History{}
LotMap["start"](r, lot, msg)
fmt.Printf("%T\n", r.handleStart)
fmt.Printf("%T\n", (*Receiver).handleStart)
}
运行结果:
func(*main.Lot, *main.History)
func(*main.Receiver, *main.Lot, *main.History)
如果将 LotMap 中的(*Receiver)变成(Receiver),ide 也会提示,提示如下:
所以方法值的本质是:编译器会将 (*Receiver).handleStart 变成 func(*Receiver, *Lot, *History)
。
3、总结
第一点:
上面的 LotMap 这种写法,其实有一个专用的词,叫做查找表。使用查找表可以避免了冗长的 if-else 或 switch-case 语句,使代码更加清晰、易于维护。
第二点:
在Go语言中,(*Receiver).handleStart
这种形式是方法值(method value)的写法,可以将方法绑定到特定的接收者实例上,从而创建一个函数值(function value)。在这种写法中,方法接收者(receiver)会被作为第一个参数传递给方法。
因此,(*Receiver).handleStart
可以转换为func(r *Receiver, lot *Lot, msg *History)
的函数签名,其中r *Receiver
就对应方法接收者,而lot *Lot
和msg *History
则是方法的其他参数。
这种转换允许将方法作为普通函数一样传递给其他函数或者存储在映射(map)中,使得代码更加灵活和易于组织。
golang中关于map的value类型定义为函数类型时(方法值)的一点点思考的更多相关文章
- 1.4.2 solr字段类型--(1.4.2.1)字段类型定义和字段类型属性
1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...
- golang中的map
1. 声明与初始化 // map的声明与初始化 userInfo := map[string]string{"name": "马亚南", "age&q ...
- python3中内建函数map()与reduce()的使用方法
map()的使用 map()的使用方法形如map(f(x),Itera).对,它有两个参数,第一个参数为某个函数,第二个为可迭代对象.如果不懂什么是函数,不懂什么是可迭代对象没关系,记住下面的例 ...
- Django中利用filter与simple_tag为前端自定义函数的实现方法
转自:http://www.jb51.net/article/116303.htm 前言 Django的模板引擎提供了一般性的功能函数,通过前端可以实现多数的代码逻辑功能,这里称之为一般性,是因为它仅 ...
- JS基础语法---函数---介绍、定义、函数参数、返回值
函数: 把一坨重复的代码封装,在需要的时候直接调用即可 函数的作用: 代码的重用 函数需要先定义,然后才能使用 函数名字:要遵循驼峰命名法 函数一旦重名,后面的会把前面的函数覆盖 Ctrl +鼠标左键 ...
- Golang中的Map(集合)
Map 是一种无序的键值对的集合.Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值. Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它.不过,Map 是无 ...
- golang中,map作为函数参数是如何传递的
当你声明一个map的时候: m := make(map[int]int) 编译器会调用 runtime.makemap: // makemap implements a Go map creation ...
- Golang的时间生成,格式化,以及获取函数执行时间的方法
最近都在通过完成一些列功能强化自己对常用api的熟悉. 然而关于时间的api几乎是最常用的api类型,所以总结一些常用的. 以YY-mm-dd HH:MM:SS.9位 输出当前时间: func mai ...
- Vue组件库新增的prop属性类型是Object或者Array时默认值的设置
在Vue开发中提供组件库时常常需要添加相关属性,用来接收父组件向子组件传递的数据,通常也会给属性设置默认值,那么当属性的类型是Object或者Array类型时如何设置默认值比较合理呢?下面将揭晓这一过 ...
- Go_14:GoLang中 json、map、struct 之间的相互转化
1. golang 中 json 转 struct <1. 使用 json.Unmarshal 时,结构体的每一项必须是导出项(import field).也就是说结构体的 key 对应的首字母 ...
随机推荐
- [转帖]Cat导致内存不足原因分析
背景 线上几亿的数据在回刷的时候容器服务会出现OOM而重启,导致任务中断 内存泄露分析 jmap -histo pid 找出了有几十亿的java.lang.StackTraceElement对象,找不 ...
- redis 6源码解析之 object
redis对象作为redis存储的基本单元,对应redisDb->dict 中的dictEntry->key和dictEntry->val. 更全面的图谱 源码解析参见:object ...
- fiddler如何抓取https请求
pc端browse 1.打开下载好的fiddler,点击tools选择options后进入https tab下,勾选Decrypt HTTPS CONNECTS 和Ignore server cer ...
- 什么是PWA 应用?核心技术有哪些
在国内由于小程序的风生水起,PWA 应用在国内的状况一直都不是很好,PWA 和小程序有很多的相似性,但是 PWA 是由谷歌发起的技术,小程序是微信发起的技术,所以小程序在国内得到了大力的扶持,很快就在 ...
- 浅析大促备战过程中出现的fullGc,我们能做什么?
作者:京东科技 白洋 前言: 背景: 为应对618.双11大促,消费金融侧会根据零售侧大促节奏进行整体系统备战.对核心流量入口承载的系统进行加固优化,排除系统风险,保证大促期间系统稳定. 由于大促期间 ...
- PE格式:实现ELF结构解析工具
ELF文件格式,是一个开放的可执行文件和链接文件格式,其主要工作在Linux系统上,是一种用于二进制文件.可执行文件.目标代码.共享库和核心转储格式文件,ELF文件格式类似于PE格式,但比起PE结构来 ...
- libuv计时器
目录 1.uv_timer_t - 计时器句柄 2.API 2.1.uv_timer_init 2.2.uv_timer_start 2.3.uv_timer_stop 2.4.uv_timer_ag ...
- 股价暴跌11% 但是Intel的“王者归来”时刻不远了
当地时间1月25日美国股市盘后,处理器大厂Intel公布了2023财年第四季(截至2023年12月30日为止)及2023财年全年的财报,虽然四季度业绩整体优于分析师的预期,但是2024年第一季的业绩指 ...
- VS Code 使用
Tips 总结 1. VSCode显示空格和tab符号 1.打开setting,在搜索框中输入renderControlCharacters,选中勾选框,即可显示tab 2.在搜索框中输入render ...
- (C语言)每日代码||2023.12.25||函数传参,传入数组时传递的是数组首元素地址
向函数传入某数组时,可以在函数内修改该数组的元素. #include <stdio.h> void test(char* p, char arr[]) { *p = 'h';//能改变 * ...