Go语言跨包调用结构体方法报错:GetBookings未被models包声明
解决Go语言中“GetBookings not declared by package models”报错
你遇到的问题核心是:GetBookings是BookingModel结构体的方法,并非包级别的全局函数,Go语言要求结构体方法必须通过该结构体的实例调用,不能直接用包名调用。以下是两种可行的修正方案:
方案一:初始化结构体实例调用方法
这种方式符合面向对象的封装逻辑,适合需要复用数据库连接实例的场景。
修正后的Controller代码
package controllers import ( "encoding/json" "net/http" "github.com/Coddyy/beautyfly/pkg/models" // 假设你有一个负责初始化数据库连接的包,示例为db "github.com/Coddyy/beautyfly/pkg/db" ) func GetBookings(w http.ResponseWriter, r *http.Request) { // 创建BookingModel实例,传入已初始化的数据库连接 bookingModel := models.BookingModel{Db: db.GetDB()} // 通过实例调用方法 bookings, err := bookingModel.GetBookings() // 必须处理错误,避免程序静默失败 if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return } res, _ := json.Marshal(bookings) w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(res) }
优化后的Model代码(补充资源释放)
package models import ( "database/sql" "github.com/Coddyy/beautyfly/pkg/entities" ) type BookingModel struct { Db *sql.DB } func (bookingModel *BookingModel) GetBookings() ([]entities.Booking, error) { rows, err := bookingModel.Db.Query("SELECT * FROM bookings") if err != nil { return nil, err } // 延迟关闭rows,避免数据库连接泄漏 defer rows.Close() bookings := []entities.Booking{} for rows.Next() { var id int64 var customer_ids string var date string var time string var service_ids string var comments string err := rows.Scan(&id, &customer_ids, &date, &time, &service_ids, &comments) if err != nil { return nil, err } booking := entities.Booking{id, customer_ids, date, time, service_ids, comments} bookings = append(bookings, booking) } // 检查遍历rows后的潜在错误 if err := rows.Err(); err != nil { return nil, err } return bookings, nil }
方案二:改为包级全局函数
如果查询逻辑不需要依赖结构体状态,可以将方法改为包级函数,直接通过包名调用。
修正后的Model代码
package models import ( "database/sql" "github.com/Coddyy/beautyfly/pkg/entities" ) type BookingModel struct { Db *sql.DB } // 包级函数,需要传入数据库连接作为参数 func GetBookings(db *sql.DB) ([]entities.Booking, error) { rows, err := db.Query("SELECT * FROM bookings") if err != nil { return nil, err } defer rows.Close() bookings := []entities.Booking{} for rows.Next() { var id int64 var customer_ids string var date string var time string var service_ids string var comments string err := rows.Scan(&id, &customer_ids, &date, &time, &service_ids, &comments) if err != nil { return nil, err } booking := entities.Booking{id, customer_ids, date, time, service_ids, comments} bookings = append(bookings, booking) } if err := rows.Err(); err != nil { return nil, err } return bookings, nil }
对应的Controller调用代码
bookings, err := models.GetBookings(db.GetDB()) // 直接传入数据库连接调用
内容的提问来源于stack exchange,提问作者Abhra Sarkar
相关产品推荐
相关产品推荐

