我正在努力了解Go的频道。我想我理解基本的双向知识,chan但是我在理解<-chan和理解方面欠缺chan<-。
我希望它们对于与线程通信的一种方式很有用,但是我在实际读取和接收值的线程方面遇到问题。
package main
import (
"fmt"
"time"
)
func Thread(c chan<- int) {
for {
num := <-c
fmt.Println("Thread : ", num)
time.Sleep(time.Second)
}
}
func main() {
c := make(chan<- int, 3)
go Thread(c)
for i := 1; i <= 10; i++ {
c <- i
}
for len(c) > 0 {
time.Sleep(100)
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试使用<-chan,而不是chan<-在make(),但这样的事情发生了:
C:\>go run chan.go
# command-line-arguments
.\chan.go:10: invalid operation: <-c (receive from send-only type chan<- int)
Run Code Online (Sandbox Code Playgroud)
如果我无法从频道中读取内容,为什么还要打扰呢?考虑到这种想法,我认为我一定做错了什么。我曾期望仅发送chan将意味着一个线程只能发送而另一个线程只能接收。似乎并非如此。
如果我将其<-全部删除,它可以工作,但是那将使其成为双向的,从而使go例程能够响应(即使它从未执行过),而我正寻求避免这种情况。似乎我可以将数字排除在一个chan我永远无法读取的数字上,或者可以从一个chan无法写入的数字读取。
我希望做的是将整数从主线程发送到go例程,以便使用单向通道进行打印。我究竟做错了什么?
如果重要的话,这与Windows上的go 1.3.3一起使用。更新到1.4并没有帮助。我可能想提一下,这也是x64。
通道提供了一种机制,用于通过发送和接收指定元素类型的值来同时执行功能以进行通信。未初始化通道的值为nil。
Run Code Online (Sandbox Code Playgroud)ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .可选的<-运算符指定发送或接收的通道方向。如果没有给出方向,则该信道是双向的。通道只能通过转换或分配来限制发送或接收。
您可以通过转换或分配来明确了解通道方向。例如,通过转化,
package main
import (
"fmt"
"time"
)
func Thread(r <-chan int) {
for {
num := <-r
fmt.Println("Thread : ", num)
time.Sleep(time.Second)
}
}
func main() {
c := make(chan int, 3)
s, r := (chan<- int)(c), (<-chan int)(c)
go Thread(r)
for i := 1; i <= 10; i++ {
s <- i
}
for len(c) > 0 {
time.Sleep(100)
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
线程:1 线程:2 线程:3 。。。
或者,等效地,通过分配,
package main
import (
"fmt"
"time"
)
func Thread(r <-chan int) {
for {
num := <-r
fmt.Println("Thread : ", num)
time.Sleep(time.Second)
}
}
func main() {
c := make(chan int, 3)
var s chan<- int = c
var r <-chan int = c
go Thread(r)
for i := 1; i <= 10; i++ {
s <- i
}
for len(c) > 0 {
time.Sleep(100)
}
}
Run Code Online (Sandbox Code Playgroud)