You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 16:15:30