为了账号安全,请及时绑定邮箱和手机立即绑定

类型接口的通道没有在 Golang 中使用 MySql 接收值

类型接口的通道没有在 Golang 中使用 MySql 接收值

Go
杨__羊羊 2022-03-03 15:09:14
我是golang的新手。我正在尝试使用 golang 对 mysql db 进行并发查询。我知道频道可以是接口类型。tableData (type map)当我在函数中打印时,RunQuery我得到了结果。我正在发送tableData到ch类型接口的 ie 通道。在函数getdataList中我没有得到任何价值ch。我不明白我做错了什么。以下是我的代码:package mainimport (    "database/sql"    "fmt"    "net/http"    _ "github.com/go-sql-driver/mysql"    "log")var db *sql.DBfunc getdataList(id int) {        ch := make(chan interface{})        done := make (chan bool)        RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)        go func() {            for {            x, ok := <-ch //I am not getting any data in channel here            if ok {                fmt.Println(x)            }else {                fmt.Println("done")                done <- true                return            }        }        }()    }func RunQuery (ch chan interface{}, query string, param interface{}) {    stmt, err := db.Prepare(query)    if err != nil {                panic(err.Error())            }    defer stmt.Close()    rows, err := stmt.Query(param)    columns, err := rows.Columns()    if err != nil {        fmt.Println("Failed to get columns", err)        return    }    count := len(columns)    tableData := make([]map[string]interface{}, 0)    values := make([]interface{}, count)    valuePtrs := make([]interface{}, count)    for rows.Next() {      for i := 0; i < count; i++ {          valuePtrs[i] = &values[i]      }      rows.Scan(valuePtrs...)      entry := make(map[string]interface{})      for i, col := range columns {          var v interface{}          val := values[i]          b, ok := val.([]byte)          if ok {              v = string(b)          } else {              v = val          }          entry[col] = v      }      tableData = append(tableData, entry)  }    fmt.Pritln(tableData) //here I am getting data in map    ch <- tableData}func dbtest(w http.ResponseWriter, req *http.Request) {    go getdataList(2)    go getdataList(3)}
查看完整描述

1 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

您的代码的问题在于它在从通道读取数据之前阻塞了执行流程。当您调用RunQueryfromgetdataList时,RunQuery尝试通过 channel 发送数据ch。但是,没有读取任何内容,ch因为要从中读取的代码位于其中,getdataList并且位于对RunQuery.


因此,RunQuery永远不会返回并且要从中读取的 goroutinech永远不会触发。要修复,您也可以尝试RunQuery作为 goroutine 运行:


func getdataList(id int) {

        ch := make(chan interface{})

        done := make (chan bool)

        // run in a goroutine

        go RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)

        go func() {

            for {

            x, ok := <-ch //I am not getting any data in channel here

            if ok {

                fmt.Println(x)

            }else {

                fmt.Println("done")

                done <- true

                return

            }


        }

    }()

}

您的代码中还有另一个问题。你永远不会关闭ch。这可能会导致死锁。最理想的地方似乎是RunQuery:


func RunQuery (ch chan interface{}, query string, param interface{}) {

    // ...

    ch <- tableData

    close(ch)

}


查看完整回答
反对 回复 2022-03-03
  • 1 回答
  • 0 关注
  • 268 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号