doubao6464 2013-08-08 17:01 采纳率: 100%
浏览 28
已采纳

为什么在db.Prepare之后更改`votes`的值?

I am using http://github.com/Go-SQL-Driver/MySQL

I want to get a value votes like "0000" from database and update it into "1000". Before db.Prepare() it works normally. But after it, the value of votes is changed. I didn't do anything with it except db.Prepare(). My code is

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
}

the Votes type is :

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
}

Finally I copy the value from votes into v and it works well. I can not understand why the value of votes is changed. Is there anything wrong with my code? Any help would be appreciated.

  • 写回答

1条回答 默认 最新

  • duanqianpu6499 2013-08-17 19:05
    关注

    I think the problem lies in the statement:

    res.Scan(&votes)
    

    which should be:

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

    the *Votes you pass on to Scan will not be identified as *[]byte unless you make an assertion.

    Here is an example that clearly shows the identification problem:

    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))
    }
    

    The code above prints:

    <nil> false
    &[104 101 108 108 111] true
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 请教 麒麟系统挂载怎么安装
  • ¥15 如何在ns3中实现路径的自由切换
  • ¥20 SpringBoot+Vue3
  • ¥15 IT从业者的调查问卷
  • ¥65 LineageOs-21.0系统编译问题
  • ¥30 关于#c++#的问题,请各位专家解答!
  • ¥15 App的会员连续扣费
  • ¥15 不同数据类型的特征融合应该怎么做
  • ¥15 用proteus软件设计一个基于8086微处理器的简易温度计
  • ¥15 用联想小新14Pro