使用GORM调用Error()报错:cannot call non-function问题求助
GORM调用Error()报错原因分析
问题
编译时触发错误:
invalid operation: cannot call non-function mysql.MysqlDB.Save(product).Error (variable of type error)
场景:模仿网课开发项目,用GORM替代老师手写的数据库层操作时出现该编译错误。
错误的服务层代码
package service import ( "iris-seckill/db/mysql" "iris-seckill/model" ) type IProductService interface { GetProductByID(int64) (*model.Product, error) GetAllProduct() ([]*model.Product, error) DeleteProductByID(int64) error InsertProduct(product *model.Product) (int64, error) UpdateProduct(product *model.Product) error } type ProductService struct { } func NewProductService() IProductService { return &ProductService{} } func (p *ProductService) GetProductByID(productID int64) (*model.Product, error) { var product model.Product err := mysql.MysqlDB.Where("product_id = ?", productID).First(&product).Error() if err != nil { return nil, err } return &product, nil } func (p *ProductService) GetAllProduct() (res []*model.Product, err error) { err = mysql.MysqlDB.Find(&res).Error() return } func (p *ProductService) DeleteProductByID(productID int64) error { err := mysql.MysqlDB.Where("product_id = ?", productID).Delete(&model.Product{}).Error() return err } func (p *ProductService) InsertProduct(product *model.Product) (int64, error) { err := mysql.MysqlDB.Create(product).Error() if err != nil { return 0, err } return product.ProductID, nil } func (p *ProductService) UpdateProduct(product *model.Product) error { err := mysql.MysqlDB.Save(product).Error() return err }
解决后的服务层代码
package service import ( "iris-seckill/db/mysql" "iris-seckill/model" ) type IProductService interface { GetProductByID(int64) (*model.Product, error) GetAllProduct() ([]*model.Product, error) DeleteProductByID(int64) error InsertProduct(product *model.Product) (int64, error) UpdateProduct(product *model.Product) error } type ProductService struct { } func NewProductService() IProductService { return &ProductService{} } func (p *ProductService) GetProductByID(productID int64) (*model.Product, error) { var product model.Product mysql.MysqlDB.Where("product_id = ?", productID).First(&product) return &product, nil } func (p *ProductService) GetAllProduct() (res []*model.Product, err error) { mysql.MysqlDB.Find(&res) return } func (p *ProductService) DeleteProductByID(productID int64) error { mysql.MysqlDB.Where("product_id = ?", productID).Delete(&model.Product{}) return nil } func (p *ProductService) InsertProduct(product *model.Product) (int64, error) { mysql.MysqlDB.Create(product) return product.ProductID, nil } func (p *ProductService) UpdateProduct(product *model.Product) error { mysql.MysqlDB.Save(product) return nil }
原因说明
GORM链式调用返回的*gorm.DB结构体中,Error是error类型的成员变量,不是可调用的函数。你之前的代码错误地将它当作函数使用(加了()),导致编译报错。
另外需要注意:你解决后的代码虽然能运行,但完全丢失了错误检查逻辑,这在生产环境中很危险。正确的写法应该是直接获取Error字段的值,示例如下:
func (p *ProductService) GetProductByID(productID int64) (*model.Product, error) { var product model.Product dbResult := mysql.MysqlDB.Where("product_id = ?", productID).First(&product) if dbResult.Error != nil { return nil, dbResult.Error } return &product, nil }
其他数据库操作方法也应该按照这个方式处理错误,避免遗漏数据库操作中的异常情况。
内容的提问来源于stack exchange,提问作者Tsing Bob
相关产品推荐
相关产品推荐

