roshkattu
roshkattu

Reputation: 251

Convert a variable []interface{} into variable ...interface{} in go

I am using a go mysql library to perform several database tasks. Given the fact that I want to write a wrapper package over the mysql library, I found myself into the following situation:

I have a method with the following signature:

func(db *MySQL) Insert(query string, args ...interface{}) (int64, error)

This method is calling the db.Exec function from the library which has the following signature:

func (db *DB) Exec(query string, args ...interface{}) (Result, error)

It seems that when I call my method Insert("some query", 1, "test") the values ...interface{} is translated into []interface{} type which is incompatible to the Exec functions argument args ...interface{}.

Q1: By understanding this situation and having in consideration that I can't modify the signature of Exec function, how would it be possible for me to transfer the args from my Insert function to the Exec function?

I have tried several things to implement this but it seems I cannot achieve nor find a way to put my arguments in that function call.

Q2: Is this even possible without modifying the signature of Exec ?

Edit: This is an example of what I am trying to achieve with the above functionality:

func(db *MySQL) Insert(query string, values ...interface{}) (int64, error) {
    /**
     * TODO: find a way to implement the args slice
     * to implement this remember that behind Exec(_, values) there is a [] interface{} element
     * which will decompose this element inside. so by passing a values ...interface{} function won't work
     * as the values ...interface{} has another data type structure in the end
     */
    //
    if res, err := db.dbConn.Exec(query, values); err != nil {
        return -1, err
    } else {
        if lastId, err := res.LastInsertId(); err != nil {
            return -1, err
        } else {
            return lastId, nil
        }
    }
}

Upvotes: 0

Views: 68

Answers (1)

T. Claverie
T. Claverie

Reputation: 12256

From what I understand, your problem is that when you call Exec from Insert with the same arguments, it considers []interface{} as an interface{}. In golang, you can expand a slice with the operator .... This way you can pass the arguments from Insert to Exec.

func exec(args ...interface{}) {
    fmt.Println(args)
}

func insert(args ...interface{}) {
    exec(args)      // Prints [[5 42]]
    exec(args...)   // Prints [5 42]
}

func main() {
    insert(5, "42")
}

Upvotes: 1

Related Questions