3

I'm trying to learn type assertion and conversion. It's kinda complicated for me.

I have this example: (I'm using gin framework)

type Env struct {
    db *sql.DB
}

func main() {
    r := gin.Default()

    // Initiate session management (cookie-based)
    store := sessions.NewCookieStore([]byte("secret"))
    r.Use(sessions.Sessions("mysession", store))

    db, _ := sql.Open("sqlite3", "./libreread.db")
    defer db.Close()

    env := &Env{db: db}
    r.GET("/", env.GetHomePage)
}

func (e *Env) _GetUserId(email string) int64 {
    rows, err := e.db.Query("SELECT `id` FROM `user` WHERE `email` = ?", email)
    CheckError(err)

    var userId int64
    if rows.Next() {
        err := rows.Scan(&userId)
        CheckError(err)
    }
    rows.Close()

    return userId
}

func (e *Env) GetHomePage(c *gin.Context) {

    session := sessions.Default(c)
    email := session.Get("email")

    if email != nil {
        name := c.Param("bookname")
        userId := e._GetUserId(email) // I'm stuck here.
}

So, in the above code.. I'm setting db Env type and passing it to router functions. From there, I need to call another function. How to do that?

When I call e._GetUserId(email), it says

cannot convert email (type interface {}) to type Env: need type assertion

How to solve this problem?. Do I need to use inferface{} instead of struct for Env type?

rnk
  • 2,174
  • 4
  • 35
  • 57
  • 1
    Does `session.Get("email")` returns `interface{}` type? If yes then do type assertion for email parameter like this `e._GetUserId(email.(string))`. – jeevatkm Jun 17 '17 at 03:57
  • @jeevatkm If that's the issue, wouldn't the error message say "cannot convert ... to type **string**"? – user94559 Jun 17 '17 at 03:58
  • I don't think the error message matches up with this code... nowhere that I can see is something called `email` used where an `Env` should be. – user94559 Jun 17 '17 at 03:59
  • 1
    @jeevatkm Wow that works! But when I check it with reflect.Typeof(session.Get("email")). It says string value. Why it takes as interface{} in the function argument? – rnk Jun 17 '17 at 03:59
  • @rnk You're welcome. `reflect.Typeof` method accepts any type that's why parameter is `interface{}` returns the actual type of the value. I will post an answer so you can accept it. – jeevatkm Jun 17 '17 at 04:09
  • @smarx you're correct, error doesn't match with code. I went through provided code and took assumption based on the code and asked a clarification. – jeevatkm Jun 17 '17 at 04:10

1 Answers1

7

Drafting answer based on conversation from my comments.

Method session.Get("email") returns interface{} type.

And method e._GetUserId() accepts string parameter, so you need to do type assertion as string like -

e._GetUserId(email.(string))
jeevatkm
  • 4,571
  • 1
  • 23
  • 24