Golang笔记——包的循环引用问题(import cycle not allowed)和匿名导入

ops/2025/1/20 2:52:33/

大家好,这里是Good Note,关注 公主号:Goodnote,专栏文章私信限时Free。本文详细介绍Golang中包的循环引用问题(import cycle not allowed)和匿名导入问题。

在这里插入图片描述

文章目录

      • 循环引用问题
        • 优势
        • 设计原因
        • 解决方法
      • 明确导入的包必须使用
        • 匿名导入
    • 补充
      • 不允许隐式类型转换
    • 历史文章
      • MySQL数据库
      • Redis
      • Golang

循环引用问题

Go 的设计哲学是避免复杂的循环依赖,从而强制开发者更清晰地思考模块之间的依赖关系。这种设计使代码更易维护,也加快了编译速度。

优势

曾有人建议作者之一的Rob Pike,在以后的Go版本去掉不允许循环引入的问题;Rob Pike则认为这样设计有如下优势:

  1. 加快编译速度
  2. 规范框架设计,使项目结构更加清晰明了
设计原因

作者认为:

  • 没有支持循环引用:目的是迫使 Go 程序员更多地考虑程序的依赖关系。

    • 保持依赖关系图的简洁。

    • 快速的程序构建。

  • 如果支持循环引用:很容易会造成懒惰、不良的依赖性管理和缓慢的构建。这是设计者不希望看见的。

    • 混乱的依赖关系。

    • 缓慢的程序构建

如果在项目中出现循环引用问题,很大程度是因为设计之初就没考虑好模块的划分。

解决方法

优先考虑使用方法1

  1. 新建一个公共包,将涉及的函数或方法放到公共包当中;

    当两个包 AB 互相依赖时,可能是因为它们有某些共享的功能。如果把这些共享功能提取到一个独立的公共包(比如 common),就可以打破循环依赖。AB 可以单独依赖 common,而不需要直接依赖对方。

  2. 将循环引用的方法或者函数抽象成接口;

    通过抽象一个接口来打破直接依赖关系。假设包 A 需要调用包 B 的某些方法,而包 B 同时需要调用包 A 的方法。这时,可以将这些方法抽象成接口,由其中一个包提供接口的实现。

定义接口:让包 B 依赖接口

  • 将包 A 的功能抽象成接口 AInterface
  • B 依赖 AInterface,而不是直接依赖包 A

包 A (A/a.go)

package A// 定义接口 AInterface 
type AInterface interface {AFunction() 
}// AType 实现 AInterface 
type AType struct{}func (a *AType) AFunction() {println("AFunction is called") 
} 

包 B (B/b.go)

package B// BType 依赖 AInterface 
type BType struct {AImpl AInterface // 接口,而不是具体实现 
}func (b *BType) BFunction() {println("BFunction is called")b.AImpl.AFunction() // 调用 AInterface 的方法 
}

主程序:组合两个包 在主程序中,将包 A 和包 B 组合在一起,打破了直接依赖:


import ("A""B" )func main() {a := &A.AType{}         // 创建 AType 实例b := &B.BType{AImpl: a} // 将 A 的实现传递给 Bb.BFunction() // 调用 B 的方法,间接调用 A 的方法
} 

输出结果BFunction is called AFunction is called

  • 包 B 依赖的是 AInterface 接口,而不是包 A 的具体实现。当接口(AInterface)不是由包 A 定义,而是由包 B 本身定义或通过其他途径提供时,包 B 就完全不需要导入包 A。
  • Go 的接口机制允许我们只依赖接口,而不依赖接口的实现,从而实现解耦。这种设计是 Go 语言的关键优势。

明确导入的包必须使用

在 Go 中,如果导入了一个包但没有使用它,编译器会报错。Go 不允许“死包”导入。

设计目的:

  • 强制开发者移除无用的代码和依赖。
  • 提高代码的可读性和可维护性。

示例:

import "fmt"func main() {// 如果不使用 fmt 包,这段代码将无法编译。fmt.Println("Hello, Go!")
}
匿名导入

在 Go 中,如果导入了一个包却没有使用其中的任何内容,编译器会报错。匿名导入通过 _ 使得包被导入,但不直接使用包内的任何内容,从而避免编译错误。

  • 目的:为了触发包的 init() 函数,执行包级别的初始化逻辑,而无需显式调用包中的其他内容。

补充

不允许隐式类型转换

Go 不支持隐式类型转换,所有的类型转换必须是显式的。

设计目的:

  • 避免隐式转换带来的意外错误。
  • 使代码更加清晰和安全。

示例:

var a int = 10
var b float64 = 3.14// b = a  // 编译错误:无法将 int 隐式转换为 float64
b = float64(a)  // 显式转换,合法

对比其他语言:

  • 在 C/C++、php中,很多时候可以隐式将 int 转换为 float,容易导致一些不易察觉的精度问题或错误。

历史文章

MySQL数据库

MySQL数据库

Redis

Redis数据库笔记合集

Golang

  1. Golang笔记——语言基础知识
  2. Golang笔记——切片与数组
  3. Golang笔记——hashmap
  4. Golang笔记——rune和byte
  5. Golang笔记——channel
  6. Golang笔记——Interface类型
  7. Golang笔记——数组、Slice、Map、Channel的并发安全性
  8. Golang笔记——协程同步
  9. Golang笔记——并发控制
  10. Golang笔记——GPM调度器
  11. Golang笔记—— new() 、 make() 和简短声明符
  12. Golang笔记—— error 和 panic
  13. Golang——内存(内存管理、内存逃逸、垃圾回收 (GC) 机制)

http://www.ppmy.cn/ops/151542.html

相关文章

“大数据+技校”:VR虚拟仿真实训室的发展前景

在技术教育的新时代,大数据与虚拟现实技术的融合正在重塑技校的教学模式。"大数据技校"模式下的VR虚拟仿真实训室,为技校学生提供了一个创新的学习平台,预示着教育方式的深刻变革。 一、大数据与技校教育的深度融合 大数据技术的应…

Unity中实现倒计时结束后干一些事情

问题描述:如果我们想实现在一个倒计时结束后可以执行某个方法,比如挑战成功或者挑战失败,或者其他什么的比如生成boss之类的功能,而且你又不想每次都把代码复制一遍,那么就可以用下面这种方法。 结构 实现步骤 创建一…

第十一章 图论

#include <iostream> #include <cstdio> #include <vector>using namespace std;const int MAXN 1000;vector<int> graph[MAXN]; //用向量存储邻接表中的每个点及其连接的的其他点int main(){return 0; } #include <iostream> #include &…

【ROS2 中间件RMW】基于FastDDS共享内存实现ROS2跨进程零拷贝通讯

前言 谈及ROS2的通讯机制&#xff0c;话题通讯作为一个最为常用的通讯手段&#xff0c;相信大家都不为陌生。但是即便话题通讯提供了一种跨进程的通讯方式&#xff0c;我们难免无法防止其在发布和订阅 的时候传递的消息被进行内存中的一次拷贝。因此诞生了零拷贝(zero_copy)这…

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路&#xff1a; 攻击外网服务器&#xff0c;获取外网服务器的权限&#xff0c;接着利用入侵成功的外网服务器作为跳板&#xff0c;攻击内网其他服务器&#xff0c;最后获得敏感数据&#xff0c;并将数据传递到攻击者&#xff0…

基于微信小程序的校园运动场地预约系统设计与实现

一.前言 选题背景&#xff1a; 随着社会的进步和人们生活水平的提高&#xff0c;健康意识逐渐增强&#xff0c;越来越多的人开始关注和参与体育运动。在校园中&#xff0c;学生们也积极参与各种体育活动&#xff0c;以提升身体素质和促进全面发展。然而&#xff0c;由于校园运动…

[Qualcomm]Qualcomm MDM9607 SDK代码下载操作说明

登录Qualcomm CreatePoing Qualcomm CreatePointhttps://createpoint.qti.qua

记录一次微信小程序使用云能力开发的过程

对于开发微信小程序云开发不知从何起的同学们&#xff0c;可以当作一次参考。虽说官方有文档&#xff0c;有模板示例&#xff0c;但是这些都是片段或者完整的结果展示。对于初学或者开发经验较少的同学们&#xff0c;可能不知先从那里入手进行第一步的开发。下面解析下构建微信…