Go中Commando库CommandRegistry的*Command指针含义及取值方法
问题解答
1. 能否获取Command实例
完全可以,你可以通过*运算符解引用指针拿到Command类型的实例,示例代码如下:
// 遍历Commands Map for cmdName, cmdPtr := range commandRegistry.Commands { // 手动解引用获取Command实例 cmdInstance := *cmdPtr // 读取实例属性,比如获取命令的描述信息 println(cmdName, cmdInstance.Description) }
补充说明:Go自带指针语法糖,你不需要手动解引用也可以直接通过指针访问结构体的属性,写法cmdPtr.Description和上面的cmdInstance.Description效果完全一致,编译器会自动完成解引用操作。
2. 类型声明使用*Command的原因
主要有4个核心原因:
- 降低拷贝开销:如果直接存储
Command值类型,每次从Map取值、或者传递参数时都会完整拷贝整个结构体的所有内容,当Command结构体字段多、体积大时会造成不必要的性能损耗和内存浪费,指针在64位系统上仅占8字节,拷贝成本极低。 - 支持原地修改:如果存储值类型,你从Map中拿到的只是原始数据的拷贝,修改拷贝不会影响Map中存储的原始内容;使用指针的情况下,修改指针指向的内容,所有引用该指针的位置都能拿到最新的修改结果,适配命令注册后运行时调整配置的需求。
- 支持空值占位:指针类型可以合法赋值为
nil,可以满足部分未完成初始化的命令临时占位的需求,值类型则必须完成初始化后才能使用,无法实现空值占位。 - 符合Go开发惯例:对于需要跨模块共享、或可能被修改的结构体实例,Go社区通常都会选择用指针存储和传递,你可以简单把Go的结构体指针理解为你之前在Java中使用的对象引用,Go的指针不支持指针运算,安全性很高,不需要担心C类指针的各类安全问题。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

