我正在探索Go并试图使用频道设置一种管道。我只想读取main()中的内容并将它们发送到process()进行处理,在这种情况下只需将值打印到屏幕上。
不幸的是,在下面的代码中,似乎process()从不从频道中读取,或者至少它没有打印任何东西;我做错了什么?
package main
import ( "fmt" ; "database/sql" ; _ "github.com/lib/pq" ; "time" ; "gopkg.in/redis.v3" )//; "strconv" )
type Record struct {
userId, myDate int
prodUrl string
}
func main(){
//connect to db
db, err := sql.Open(...)
defer db.Close()
//error check here...
//exec query
rows, err := db.Query("select userID,url,date from mytable limit 10")
defer rows.Close()
//error check here...
//create channel to buffer rows read
bufferChan := make(chan *Record,1000)
go process(bufferChan)
//iterate through results and send them to process()
row := new(Record)
for rows.Next(){
err := rows.Scan(&row.userId, &row.prodUrl, &row.myDate)
bufferChan <- row
fmt.Printf("row sent %v",row.userId)
}
}
//prints Record values
func process (buffer chan *Record) {
row := <- buffer
fmt.Printf("row received: %d %v %d ", row.userId,row.prodUrl,row.myDate)
}
答案 0 :(得分:2)
func进程没有打印任何东西的原因是你在for循环之后func主要退出.Next结束从而退出程序。你需要做几件事。
请查看下面的代码段:
package main
import "fmt"
func main() {
bufferChan := make(chan int, 1000)
done := make(chan bool)
go process(bufferChan, done)
for i := 0; i < 100; i++ {
bufferChan <- i
}
close(bufferChan)
select {
case <-done:
fmt.Println("Done")
}
}
func process(c chan int, done chan bool) {
for s := range c {
fmt.Println(s)
}
done <- true
}
答案 1 :(得分:1)
您的主要功能退出,因此整个程序结束。它应该等待处理结束。此外,进程函数应该使用范围关键字循环遍历通道。
工作解决方案的脚手架看起来像这样:
package main
import "fmt"
func process(input chan int, done chan struct{}) {
for i := range input {
fmt.Println(i)
}
done <- struct{}{}
}
func main() {
input := make(chan int)
done := make(chan struct{})
go process(input, done)
for i := 1; i < 10; i++ {
input <- i
}
close(input)
<-done
}
答案 2 :(得分:1)
我相信您正在寻找io.pipe()
go API,它会在编写者和读者之间创建同步内存管道。这里没有缓冲。它可用于连接期望io.Reader
的代码与期望io.Writer
的代码。
在您的情况下,io.PipeWriter
是代码&#34;从数据库读取值&#34;和&#34; io.PipeReader&#34;是代码&#34;将值写入屏幕&#34;。
这里是没有任何缓冲区的流数据的示例,即bytes.Buffer
。
// Set up the pipe to write data directly into the Reader.
pr, pw := io.Pipe()
// Write JSON-encoded data to the Writer end of the pipe.
// Write in a separate concurrent goroutine, and remember
// to Close the PipeWriter, to signal to the paired PipeReader
// that we’re done writing.
go func() {
err := json.NewEncoder(pw).Encode(&v)
pw.Close()
}()
// Send the HTTP request. Whatever is read from the Reader
// will be sent in the request body.
// As data is written to the Writer, it will be available
// to read from the Reader.
resp, err := http.Post(“example.com”, “application/json”, pr)
参考:
https://medium.com/stupid-gopher-tricks/streaming-data-in-go-without-buffering-3285ddd2a1e5