Go语言中常见100问题-#14 Ignoring package name collisions
2023-02-18 16:32:46 时间
忽视包名冲突
当变量名与包名相同时会发生包冲突,会阻止包被重用。下面来看一个Redis客户端库的具体例子。
package redis
type Client struct { ... }
func NewClient() *Client { ... }
func (c *Client) Get(key string) (string, error) { ... }
上述代码保存在redis库中,现在有一个客户端程序,使用到上面的redis包提供的功能。尽管调用的包名是redis,但在Go语言中创建一个名为redis的变量是完全有效的。
redis := redis.NewClient()
v, err := redis.Get("foo")
上面这个客户端调用程序中变量名和包名都是redis,虽然语法上没有任何问题,但是应该避免这种做法。这会导致在整个redis变量的作用域范围内,redis包将无法访问。
假设在一个函数中同时使用了变量redis和包名redis,在这种情况下,阅读代码的时候可能混淆不清。有哪些方法可以避免这种冲突呢?第一种处理方法是使用不同的变量名,例如像下面变量取名为redisClient。
redisClient := redis.NewClient()
v, err := redisClient.Get("foo")
虽然上面这种做法非常直接有效,但是,如果出现某种原因我们更喜欢保留名为redis的变量,这时可以在导入包上做点文章,给导入包起一个别名,代码中使用包的别名可以避免冲突,示例程序如下。使用redisapi导入别名来引用redis包,这样就可以保留变量名redis.
import redisapi "mylib/redis"
// ...
redis := redisapi.NewClient()
v, err := redis.Get("foo")
「NOTE:还有一种做法是导包时使用 . 导入来访问没有包限定符的包中的所有公共元素。然而,这种方法往往会增加混淆,在大多数情况下应该避免使用。」
还要注意,我们应该避免变量名和内置函数名之间的名称相同冲突。例如,下面这个拷贝操作, 函数 copyFile 返回结果赋值给了变量 copy, 与内置的函数 copy 冲突了,导致内置的copy函数无法访问。我们应该防止变量名冲突以避免歧义。如果遇到冲突,我们应该找到另一个有意义的名称或使用导入包别名。
copy := copyFile(src, dst)
相关文章
- [TCP] 单台linux服务器最多支撑的tcp最大连接数
- [Go] redis分布式锁的go-redis实现
- [Go] 获取当前时间戳和时间戳单位转换
- [Go]字符串转int64数值型
- [Go] go下实现md5加密
- [Go] goland开启自动格式化和开启go modules
- [Git] git version 2以上git add .和git add -A 一样
- [Linux] 使用tcpdump查看上传文件过程中的tcp传输过程
- [Linux] 使用ifconfig查看tcp数据包的最大传输大小
- [Linux]利用tcpdump打印sql语句
- [Linux] 使用lsof命令查找进程打开的所有文件
- [Go] GO语言实战-slice的初始化影响转换成json后的数据结构
- [Go] GO语言实战-使用append函数要重新赋值
- [GOFLY在线客服系统] 开源版与商务版的区别
- [git] git stash 暂存未提交的修改文件
- [Go]Go语言实战-jwt-go会把存储的数值型转成float64
- [Go]GO语言实战-类型声明语句
- [linux] unzip把压缩文件解压到指定目录下 -d
- [git] git status命令查看文件状态
- [Go] gin框架中增加pprof分析性能