2013-08-08 2 views
0

Я использую http://github.com/Go-SQL-Driver/MySQLПочему значение `голосов` изменяется после db.Prepare?

Я хочу, чтобы получить значение votes как «0000» из базы данных и обновлять его в «1000». До db.Prepare() он работает нормально. Но после этого изменяется значение votes. Я ничего с этим не делал, кроме db.Prepare(). Мой код

func Vote(_type, did int, username string) (isSucceed bool) { 
    db := lib.OpenDb() 
    defer db.Close() 

    stmt, err := db.Prepare(
     `SELECT votes 
FROM users 
WHERE username = ?`) 
    lib.CheckErr(err) 

    res := stmt.QueryRow(username) 
    stmt.Close() 

    var votes Votes 
    res.Scan(&votes) 
    fmt.Println(votes)//output: [48 48 48 48] 
    fmt.Println(string(votes))//output: 0000 

    isSucceed = votes.add(VoteType(_type), 1) 
    fmt.Println(votes)//output: [49 48 48 48] 
    fmt.Println(string(votes))//output: 1000 

    //v := []byte{[]byte(votes)[0], []byte(votes)[1], []byte(votes)[2], []byte(votes)[3]} 

    if isSucceed { 
     //Update user votes 
     stmt, err := db.Prepare(
      `UPDATE users 
SET votes = ? 
WHERE username = ?`) 
     lib.CheckErr(err) 

     fmt.Println(votes)//output: [4 254 0 0] 
     fmt.Println(string(votes))//output: [EOT]□[NUL][NUL] 
     //_, _ = stmt.Exec(v, username) 
     _, _ = stmt.Exec(votes, username) 
     stmt.Close() 

     //Insert the vote data 
     stmt, err = db.Prepare(
      `INSERT votes 
SET did = ?, username = ?, date = ?`) 
     lib.CheckErr(err) 

     today := time.Now() 
     _, _ = stmt.Exec(did, username, today) 
     stmt.Close() 
    } 

    return 
} 

Votes тип:

type Votes []byte 
type VoteType int 

func (this *Votes) add(_type VoteType, num int) (isSucceed bool) { 
    if []byte(*this)[_type] > VOTE_MAX-1 { //beyond 
     isSucceed = false 
    } else { 
     []byte(*this)[_type]++ 
     isSucceed = true 
    } 
    return 
} 

Наконец скопировать значение из votes в v и он хорошо работает. Я не могу понять, почему изменяется значение votes. Что-то не так с моим кодом? Любая помощь будет оценена по достоинству.

+0

Беглого чтение коды указует на то, что не изменится. Вы уверены, что это действительно так? –

+0

Да, я уверен, что он изменился. Я думаю, это действительно странно. –

ответ

0

Я думаю, что проблема заключается в утверждении:

res.Scan(&votes) 

, которые должны быть:

res.Scan((*[]byte)(&votes)) 

* Голосов Вы передаете для сканирования не будет идентифицирован как * [] байт, если вы сделать утверждение.

Вот пример, который ясно показывает проблему идентификации:

package main 

import "fmt" 

type BYTES []byte 
func test(v interface{}) { 
    b, ok := v.(*[]byte) 
    fmt.Println(b, ok) 
} 

func main() { 
    p := BYTES("hello") 
    test(&p) 
    test((*[]byte)(&p)) 
} 

Код выше принтов:

<nil> false 
&[104 101 108 108 111] true 
+0

Вы правы. Это исправить. Большое спасибо. –

Смежные вопросы