FAQ
I'm having some confusion about types. I'll explain what I'm trying to do
and hope the list can point me in the right direction.

I'm creating a connection to MySQL with the ziutek/mymysql package from
Github:

import (
"github.com/ziutek/mymysql/mysql"
"github.com/ziutek/mymysql/native"
)
....
func main() {
db := mysql.New("tcp", "", "127.0.0.1:5607", "root", "", "mysql")
err := db.Connect()
....
}

Now I want to pass this connection to a subroutine where it will execute
some queries. I have this all working if I keep it all in main(), but
here's where I run into trouble. I want to call the function like this:

go doSomething(&db)

I define doSomething as follows:

func doSomething(db *mysql.Conn) {
rows, meta, err := db.Query("SELECT....")
....
}

Now the compiler complains: it says type mysql.Conn has no Query function.
I used a fmt.Printf("%T", db) to look at its type, and it says
*native.Conn. This is not surprising to me because in the
mymysql/native/mysql.go file, New() returns mysql.Conn but the object it
returns is a native.Conn. So a native.Conn can obviously be assigned to a
variable of type mysql.Conn because that's an interface type, and
native.Conn must implement the interface.

OK, I think, maybe I should redefine my function prototype... but this
feels wrong, I should use the interface type, not the concrete type. I go
against my inner voice and redefine:

func doSomething(db *native.Conn) {
....
}

Now the compiler complains again: "cannot use &db (type *mysql.Conn) as
type *native.Conn in function argument"

Hmm. This is kind of strange to me; it's counterintuitive that the compiler
would let me call Query() on db, a variable whose inferred/virtual (what's
the Go-ism to say here?) type is mysql.Conn (is it though?) due to the
return type of New(), when that type doesn't define Query(), and only the
concrete type native.Conn defines that function.

Am I doing something stupid, or do I not understand how types are inferred
and their relationships, or is the problem that the package is using types
awkwardly, or...?

Should I be using only the types and operations defined in the file
mysql/interface.go? It seems to me each of the drivers ought to fully
implement those interfaces, and I should pass things around without knowing
what the concrete types of the variables are. But it looks like I need to
use the combination of two interfaces, Conn and ConnCommon, which looks
strange to me -- is that idiomatic? Should I be working with ConnCommon
interface/virtual types?

I'm new enough to Go that I'm fairly confused and thought I'd ask for help
instead of banging my head against this.

Thanks in advance,
Boris

--

Search Discussions

  • Larry Clapp at Oct 30, 2012 at 9:45 pm
    Haven't tried it, but pretty sure you want to say

    go doSomething(db)

    ...

    func doSomething(db mysql.Conn) {
    rows, meta, err := db.Query("SELECT....")
    ....
    }

    mysql.Conn is an interface; you needn't take its address or pass a pointer.

    I think. Not an expert either.

    -- L

    On Tuesday, October 30, 2012 1:47:41 PM UTC-4, Boris wrote:

    I'm having some confusion about types. I'll explain what I'm trying to do
    and hope the list can point me in the right direction.

    I'm creating a connection to MySQL with the ziutek/mymysql package from
    Github:

    import (
    "github.com/ziutek/mymysql/mysql"
    "github.com/ziutek/mymysql/native"
    )
    ....
    func main() {
    db := mysql.New("tcp", "", "127.0.0.1:5607", "root", "", "mysql")
    err := db.Connect()
    ....
    }

    Now I want to pass this connection to a subroutine where it will execute
    some queries. I have this all working if I keep it all in main(), but
    here's where I run into trouble. I want to call the function like this:

    go doSomething(&db)

    I define doSomething as follows:

    func doSomething(db *mysql.Conn) {
    rows, meta, err := db.Query("SELECT....")
    ....
    }

    Now the compiler complains: it says type mysql.Conn has no Query function.
    I used a fmt.Printf("%T", db) to look at its type, and it says
    *native.Conn. This is not surprising to me because in the
    mymysql/native/mysql.go file, New() returns mysql.Conn but the object it
    returns is a native.Conn. So a native.Conn can obviously be assigned to a
    variable of type mysql.Conn because that's an interface type, and
    native.Conn must implement the interface.

    OK, I think, maybe I should redefine my function prototype... but this
    feels wrong, I should use the interface type, not the concrete type. I go
    against my inner voice and redefine:

    func doSomething(db *native.Conn) {
    ....
    }

    Now the compiler complains again: "cannot use &db (type *mysql.Conn) as
    type *native.Conn in function argument"

    Hmm. This is kind of strange to me; it's counterintuitive that the
    compiler would let me call Query() on db, a variable whose inferred/virtual
    (what's the Go-ism to say here?) type is mysql.Conn (is it though?) due to
    the return type of New(), when that type doesn't define Query(), and only
    the concrete type native.Conn defines that function.

    Am I doing something stupid, or do I not understand how types are inferred
    and their relationships, or is the problem that the package is using types
    awkwardly, or...?

    Should I be using only the types and operations defined in the file
    mysql/interface.go? It seems to me each of the drivers ought to fully
    implement those interfaces, and I should pass things around without knowing
    what the concrete types of the variables are. But it looks like I need to
    use the combination of two interfaces, Conn and ConnCommon, which looks
    strange to me -- is that idiomatic? Should I be working with ConnCommon
    interface/virtual types?

    I'm new enough to Go that I'm fairly confused and thought I'd ask for help
    instead of banging my head against this.

    Thanks in advance,
    Boris
    --
  • Rory McGuire at Oct 31, 2012 at 7:03 am
    Can I suggest that before your code gets bigger you do something like this:
    http://www.ryanday.net/2012/09/12/golang-using-channels-for-a-connection-pool/

    Then you don't pass connections around you have a connection pool in your
    program and in the functions that need a connection to the database you*just do
    *:
    // Grab a connection from the pool and type assert to our database type
    *db := dbPool.GetConnection().(*autorc.Conn)*
    // When this function exits, release our connection back to the pool
    *defer dbPool.ReleaseConnection(db)*

    Also you might as well use these imports because they are safer:
    * "github.com/ziutek/mymysql/autorc" // Auto reconnect*
    * "github.com/ziutek/mymysql/thrsafe" // thread safe queries
    *
    *
    *

    Cheers,


    On Tuesday, 30 October 2012 22:50:39 UTC+2, Larry Clapp wrote:

    Haven't tried it, but pretty sure you want to say

    go doSomething(db)

    ...

    func doSomething(db mysql.Conn) {
    rows, meta, err := db.Query("SELECT....")
    ....
    }

    mysql.Conn is an interface; you needn't take its address or pass a pointer.

    I think. Not an expert either.

    -- L

    On Tuesday, October 30, 2012 1:47:41 PM UTC-4, Boris wrote:

    I'm having some confusion about types. I'll explain what I'm trying to do
    and hope the list can point me in the right direction.

    I'm creating a connection to MySQL with the ziutek/mymysql package from
    Github:

    import (
    "github.com/ziutek/mymysql/mysql"
    "github.com/ziutek/mymysql/native"
    )
    ....
    func main() {
    db := mysql.New("tcp", "", "127.0.0.1:5607", "root", "", "mysql")
    err := db.Connect()
    ....
    }

    Now I want to pass this connection to a subroutine where it will execute
    some queries. I have this all working if I keep it all in main(), but
    here's where I run into trouble. I want to call the function like this:

    go doSomething(&db)

    I define doSomething as follows:

    func doSomething(db *mysql.Conn) {
    rows, meta, err := db.Query("SELECT....")
    ....
    }

    Now the compiler complains: it says type mysql.Conn has no Query
    function. I used a fmt.Printf("%T", db) to look at its type, and it says
    *native.Conn. This is not surprising to me because in the
    mymysql/native/mysql.go file, New() returns mysql.Conn but the object it
    returns is a native.Conn. So a native.Conn can obviously be assigned to a
    variable of type mysql.Conn because that's an interface type, and
    native.Conn must implement the interface.

    OK, I think, maybe I should redefine my function prototype... but this
    feels wrong, I should use the interface type, not the concrete type. I go
    against my inner voice and redefine:

    func doSomething(db *native.Conn) {
    ....
    }

    Now the compiler complains again: "cannot use &db (type *mysql.Conn) as
    type *native.Conn in function argument"

    Hmm. This is kind of strange to me; it's counterintuitive that the
    compiler would let me call Query() on db, a variable whose inferred/virtual
    (what's the Go-ism to say here?) type is mysql.Conn (is it though?) due to
    the return type of New(), when that type doesn't define Query(), and only
    the concrete type native.Conn defines that function.

    Am I doing something stupid, or do I not understand how types are
    inferred and their relationships, or is the problem that the package is
    using types awkwardly, or...?

    Should I be using only the types and operations defined in the file
    mysql/interface.go? It seems to me each of the drivers ought to fully
    implement those interfaces, and I should pass things around without knowing
    what the concrete types of the variables are. But it looks like I need to
    use the combination of two interfaces, Conn and ConnCommon, which looks
    strange to me -- is that idiomatic? Should I be working with ConnCommon
    interface/virtual types?

    I'm new enough to Go that I'm fairly confused and thought I'd ask for
    help instead of banging my head against this.

    Thanks in advance,
    Boris
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 30, '12 at 9:24p
activeOct 31, '12 at 7:03a
posts3
users3
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase