我正在尝试抽象我对 MySQL 数据库的使用,但我遇到了一个错误。
我将以对象为例:
package models
// Product : The Product's model
type Product struct {
ID int
Name string
Price int
PictureURL string
}
我将尝试在我的数据库中检索产品 id = 1
。为此,假设我已经连接到我的数据库,该连接由下一个变量表示:
var databaseMySQL *sql.DB
为了查询我的数据库,我使用了这个函数:
// QueryMySQL query our MySQL database
func QueryMySQL(sqlquery model.SQLQuery) model.Status {
// prepare the query
stmtOut, err := databaseMySQL.Prepare(sqlquery.Query)
if err != nil {
return model.Status{Code: http.StatusInternalServerError, Error: err}
}
defer stmtOut.Close()
// Run the query
err = stmtOut.QueryRow(sqlquery.Args).Scan(sqlquery.Dest)
if err != nil {
return model.Status{Code: http.StatusInternalServerError, Error: err}
} else {
return model.Status{Code: http.StatusOK, Error: nil}
}
}
这里使用的 2 个模型是 SQLQuery
和 Status
。
package models
type SQLQuery struct {
Query string
Args []interface{}
Dest []*interface{}
}
Status
基本上只包含一个 error
和一个 int
。
因此,由于 Scan()
作为以下原型(prototype) Scan func(dest ...interface{}) 错误
,我可以传递一个 []*接口(interface){}
作为参数。
如果我是对的,那么我应该能够让我的 Dest 元素由 T
类型元素填充,然后将它们转换/转换为类型我需要吗?
func GetProductByID(ID int) (model.Product, model.Status) {
// "SELECT ID, Name, Price, PictureURL FROM Products WHERE ID = ?"
var _product model.Product
// HERE IS THE PROBLEM
var dest []*interface{}
append(dest, &_product.Name)
append(dest, &_product.Price)
append(dest, &_product.PictureURL)
// HERE IS THE PROBLEM
status := QueryMySQL(model.SQLQuery{
Query: "SELECT Name, Price, PictureURL FROM Products WHERE ID = ?",
Args: []interface{}{ID},
Dest: dest})
return _product, model.Status{Code: http.StatusOK, Error: nil}
}
PS:这个函数只是一个基本的测试来检验我的逻辑
但是,我收到一个错误:
cannot use &_product.Name (type *string) as type *interface {} in append: *interface {} is pointer to interface, not interface
对我来说,有两个错误:
不能使用 &_product.Name(类型 *string)作为类型 *interface {}
*interface {} 是指向接口(interface)的指针,不是接口(interface)
首先,为什么我不能使用接口(interface)来存储我的字符串?
其次,由于我在字符串上传递指针,interface{}
有什么问题?它应该是 *interface{},不是吗?
正确的代码,感谢 David Budworth 的回答
除了给定的代码之外,您还可以像我一样通过在 slice 变量名称后添加 ...
将 slice 作为可变参数传递
mysqlproduct.go
// GetProductByID returns a Product based on a given ID
func GetProductByID(ID int) (model.Product, model.Status) {
_product := model.Product{
ID: ID}
status := QueryMySQL(&model.SQLQuery{
Query: "SELECT Name, Price, PictureURL FROM Products WHERE ID = ?",
Args: []interface{}{_product.ID},
Dest: []interface{}{&_product.Name, &_product.Price, &_product.PictureURL}})
if status.Code != http.StatusOK {
return _product, status
}
return _product, model.Status{Code: http.StatusOK, Error: ""}
}
mysql.go
// QueryMySQL query our MySQL database
func QueryMySQL(sqlquery *model.SQLQuery) model.Status {
stmtOut, err := databaseMySQL.Prepare(sqlquery.Query)
if err != nil {
return model.Status{Code: http.StatusInternalServerError, Error: err.Error()}
}
defer stmtOut.Close()
// Run the query
err = stmtOut.QueryRow(sqlquery.Args...).Scan(sqlquery.Dest...)
if err != nil {
return model.Status{Code: http.StatusInternalServerError, Error: err.Error()}
}
defer stmtOut.Close()
return model.Status{Code: http.StatusOK, Error: ""}
}
最佳答案
接口(interface)可以保存指针。很少有理由指向接口(interface)。
如果您将类型更改为 []interface{},它应该可以工作。
如果您确实需要指向接口(interface)的指针,出于某种原因,您必须首先将字段存储在接口(interface)中,然后获取指向该接口(interface)的指针。
即:
var i interface{} = &_product.Name
append(dest, &i)
关于mysql - 指向 MySQL 查询抽象接口(interface)的指针片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47847575/