GO 学习笔记之零 (三)常见问题处理集锦
1、Golang如何解决case-insensitive import collision问题
1.1 现象

1.2 解决方法
该问题产生说明在所有go文件中引入包时,存在 ShipModel/Radar 和 ShipModel/radar 两种写法,需要统一。
对于VSCODE工具,可以在 全局文件中搜索 ShipModel/Radar 查看 写法是不是一样,然后 进行统一,要么全部改成 ShipModel/Radar 或者全部改成 ShipModel/rada

2、panic: runtime error: invalid memory address or nil pointer dereference [recovered]
2.1 现象
代码中 在 test.go 定义了全局变量(类型为自定义类型 struct),且通过init函数对该函数进行了初始化赋值。但是在利用 gin 框架 编写了 controller 层之后 使用 net/http/httptest 进行了单元测试,单元测试代码如下:
package test import ( "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "test.com/pkg/server" "test.com/internal/controller" ) func initEngine() *gin.Engine { engine := server.Register() for _, _method := range controller.RegisterFuncs { //其中 _method 方法是 将 controller接口全部注册到 engine 引擎中,直接调用方法的时候,方法中会去执行全局变量对应类型的方法,但是此时提示 全局变量中的各个属性都是 nil。 造成单元测试执行失败 _method(engine) } return engine } func TestHelloRoute(t *testing.T) { router := initEngine() w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/api/backup/hello", nil) router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) //assert.Equal(t, "pong", w.Body.String()) }
2.2 解决方法
经过百度查找资料 发现产生的原因是,通过 init() 函数初始化 全局变量时使用了 := 导致的,需要更改成 = ,如果使用 := 表示还是局部变量
具体可参考资料: golang全局变量的一个坑,main中无法获取init初始化的变量 - 大墨垂杨 - 博客园 其中有详细说明
3、(VSCODE)单元测试调试sqlite数据库的连接性的时候,报错:failed to initialize database, got error Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub
3.1 现象

使用gorm 连接sqlite数据库,进行单元测试调试,出现以上报错
3.2 解决办法
在 Visual Studio Code (VSCode) 中运行 Go 单元测试时,可以通过以下几种方法来解决这个问题:
-
打开 VSCode 设置:
- 按
Ctrl + ,打开设置。 - 搜索
go.testEnvVars。
- 按
-
添加环境变量:
- 在
Go: Test Environment Variables设置中,添加CGO_ENABLED=1。
例如:
- 在
"go.testEnvVars": { "CGO_ENABLED": "1" }
3.3 进一步遇到的问题

3.3.1 解决办法
1)安装 最新版本的 mingw64 (Releases · niXman/mingw-builds-binaries)
- 打开github,下载最新版本的 7z 格式的成果物

- 解压到 对应目录下,将 bin 加入到系统环境变量 path下
- 配置环境变量:
- 安装完成后,需要将 MinGW 的
bin目录添加到系统的PATH环境变量中。 - 打开“控制面板” -> “系统和安全” -> “系统” -> “高级系统设置”。
- 点击“环境变量”。
- 在“系统变量”部分,找到
Path变量,点击“编辑”。 - 添加 MinGW 的
bin目录路径,例如C:\MinGW\bin。 - 点击“确定”保存设置。
- 安装完成后,需要将 MinGW 的
- 验证安装:
- 打开命令提示符(按
Win + R,输入cmd,按回车)。 - 输入
gcc --version,如果安装成功,会显示 GCC 的版本信息。
- 打开命令提示符(按
通过以上方式可以正确跑验证sqlite 连接的 单元测试用例了。
4、failed to auto migrate: unsupported data type: &[]
4.1 现象
package main import ( "log" "gorm.io/gorm" "gorm.io/driver/sqlite" ) // 定义一个结构体,表示表中的数据 type User struct { ID uint `gorm:"primaryKey"` Name string `gorm:"not null"` Age int `gorm:"not null"` } func main() { // 连接到 SQLite 数据库(如果数据库不存在,则会创建一个新的数据库) db, err := gorm.Open(sqlite.Open("example.db"), &gorm.Config{}) if err != nil { log.Fatalf("failed to connect database: %v", err) } // 自动迁移表结构 err = db.AutoMigrate(&User{}) if err != nil { log.Fatalf("failed to auto migrate: %v", err) } log.Println("Database and table created successfully!") }
在上述代码中通过 db.AutoMigrate(&User{}) 进行表自动迁移,也就是在example.db 中可以自动创建这个表,但是 有的表结构定义较负责,用到切片类型,测试,会报错 unsupported data type: &[]
4.2 解决办法
1)嵌套的切片或数组:GORM 不支持嵌套的切片或数组类型。
2)复杂的结构体:GORM 不支持嵌套的结构体类型。
3)自定义数据类型:GORM 不支持自定义的数据类型,除非你实现了 Scanner 和 Valuer 接口。
解决方法
建议使用: 实现了 Scanner 和 Valuer 接口 解决该问题
package main import ( "database/sql/driver" "errors" "strings" "gorm.io/gorm" "gorm.io/driver/sqlite" ) type User struct { ID uint Name string Tags TagList `gorm:"type:text"` } type TagList []string
//--------------------------- func (t TagList) Value() (driver.Value, error) { return strings.Join(t, ","), nil } func (t *TagList) Scan(value interface{}) error { if value == nil { *t = TagList{} return nil } str, ok := value.(string) if !ok { return errors.New("type assertion to string failed") } *t = strings.Split(str, ",") return nil }
//----------
//或者直接用json进行转换
func main() { db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) if err != nil { panic("failed to connect database") } db.AutoMigrate(&User{}) // 示例数据 user := User{ Name: "John Doe", Tags: TagList{"tag1", "tag2"}, } db.Create(&user) var result User db.First(&result, user.ID) println(result.Name) println(strings.Join(result.Tags, ",")) }
5、VSCODE 运行go程序时 报go版本不匹配
5.1 现象
工程已经配置了 lanch.json文件,点击调试中该文件对应的 调试运行按钮,出现下图所示:

5.2 解决方案
依赖库要求 go 版本是 1.23.4版本,因此需要升级工具集成的go版本,直接从官网下载匹配版本进行安装即可
6、VSCODE 运行go程序时报 3221225781
6.1 现象
运行报错,这个表示 程序运行时缺少依赖的dll库

6.2 解决方案
1)将要用的dll 文件放到 main.go 所在目录
2) 配置 lanuch.json 工作目录
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "opsmgr", "type": "go", "request": "launch", "mode": "auto", "program": "E:\\gowork\\src\\git\\xxx\\src\\test.com\\core\\start\\main.go", "cwd": "E:\\gowork\\src\\git\\xxx\\src\\test.com\\core\\start", // 工作目录 // "env": { // "PATH": "${env:PATH};E:\\gowork\\src\\git\\xxx\\src\\test.com\\base\\identify\\win64\\Identify.dll", // 添加DLL目录 ---- 这样配置无效,不知道为啥 // }, "trace": "verbose", "showLog": true } ] }


浙公网安备 33010602011771号