用于MySQL查询抽象的接口的一些指针

时间:2017-12-16 16:10:15

标签: mysql pointers go interface slice

我正在尝试抽象我对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基本上只包含errorint

因此,由于Scan()作为以下原型Scan func(dest ...interface{}) error,我可以传递[]*interface{}作为参数。

如果我是对的,那么我应该能够通过T类型元素填充 Dest 的元素,然后将它们转换/转换为我需要的类型?

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:此功能只是尝试我的逻辑的基本测试

然而,我收到一个错误:

  

不能在附加中使用& _product.Name(type * string)作为类型* interface {}:       * interface {}是指向接口的指针,而不是接口

对我来说,有两个错误:

  • cannot use &_product.Name (type *string) as type *interface {}
  • *interface {} is pointer to interface, not interface

首先,为什么我不能使用接口存储我的字符串?

其次,由于我在字符串上传递指针,interface{}有什么问题?它应该是* interface {},不是吗?

正确的代码,感谢David Budworth的回答

除了给定的代码之外,你可以通过在切片变量的名称之后添加...来像我一样传递切片

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: ""}
}

1 个答案:

答案 0 :(得分:1)

接口可以保存指针。很少有理由指向接口。

如果您将类型更改为[] interface {},它应该可以正常工作。

如果你真的想要接口指针,出于某种原因,你必须首先将该字段存储在一个接口中,然后获得指向它的指针。

即:

var i interface{} = &_product.Name
append(dest, &i)