0

http://github.com/Go-SQL-Driver/MySQLを使用しています

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
}

最後に値をにコピーするvotesv、うまく機能します。votesの値が変更される理由がわかりません。私のコードに何か問題がありますか? どんな助けでも大歓迎です。

4

1 に答える 1

0

問題は次のステートメントにあると思います。

res.Scan(&votes)

次のようになります。

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

アサーションを行わない限り、Scan に渡す *Votes は *[]byte として識別されません。

識別の問題を明確に示す例を次に示します。

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
于 2013-08-17T19:05:19.593 に答える