duanneng2014 2014-12-24 20:55
浏览 87
已采纳

如何使用<-chan和chan <-进行单向通信?

I'm working on understanding Go's channels. I think I understand a basic bidirectional chan but I'm falling short at understanding <-chan and chan<-.

I expected them to be useful for communicating one way to a thread but I'm having issues with the thread actually reading and receiving the value.

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

I've tried using <-chan instead of chan<- in the make() but the same kind of thing happens:

C:\>go run chan.go
# command-line-arguments
.\chan.go:10: invalid operation: <-c (receive from send-only type chan<- int)

If I can't read from the channel, why bother writing to it? With that thought in mind, I figure I must be doing something wrong. I had the expectation that a send only chan would mean that one thread can only send while the other thread can only receive. This does not seem to be the case.

If I remove the <- entirely, it works, but that would make it bidirectional allowing the go routine to respond (even though it never does) and I'm looking to avoid that. It seems like I can banish numbers to a chan that I'll never be able to read from, or that I could read from a chan that's impossible to write to.

What I'm hoping to do is send integers from the main thread to the go routine for it to print using a one way channel. What am I doing wrong?

This is with go 1.3.3 on Windows if it matters. Updating to 1.4 didn't help. I might want to mention this is all x64 as well.

  • 写回答

3条回答 默认 最新

  • du155305 2014-12-24 21:44
    关注

    The Go Programming Language Specification

    Channel types

    A channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil.

    ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
    

    The optional <- operator specifies the channel direction, send or receive. If no direction is given, the channel is bidirectional. A channel may be constrained only to send or only to receive by conversion or assignment.

    You can be explicit about channel direction by conversion or assignment. For example, by conversion,

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

    Output:

    Thread :  1
    Thread :  2
    Thread :  3
    . . .
    

    Or, equivalently, by assignment,

    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)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条