Golang:为什么这个ac变量初始化为chan time.Duration而不是chan chan time.Duration?

时间:2018-10-09 08:03:24

标签: go

新地鼠在这里。以下代码对我有用,但是我对doStuff函数感到困惑。为什么ac变量的确是chan time.Duration类型,而不是chan chan time.Duration类型?

package main

import (
  "log"
  "sync"
  "time"
)

// the function to be run inside a goroutine. It receives a channel on ch, sleeps for t, then sends t
// on the channel it received
func doStuff(t time.Duration, ch <-chan chan time.Duration) {
  ac := <-ch
  time.Sleep(t)
  ac <- t
}

func main() {
  // create the channel-over-channel type
  sendCh := make(chan chan time.Duration)

  recvCh := make(chan time.Duration)

  // use this to block until all goroutines have received the ack and logged
  var wg sync.WaitGroup

  // start up 10 doStuff goroutines
  for i := 0; i < 10; i++ {
    go doStuff(time.Duration(i+1)*time.Second, sendCh)
    // send channels to each doStuff goroutine. doStuff will "ack" by sending its sleep time back
    sendCh <- recvCh
    wg.Add(1)
    go func() {
      defer wg.Done()
      log.Printf("slept for %s", <-recvCh)
    }()
  }

  wg.Wait()
}

ac:= <-ch在做什么,为什么ac <-t不起作用?

我试图做的第一件事就是删除ac变量,因为起初它似乎是不必要的额外步骤,但是这样做会使输出是顺序的而不是并发的:

func doStuff(t time.Duration, ch <-chan chan time.Duration) {
  time.Sleep(t)
  <- ch <- t
}

所以我开始尝试,对我来说似乎只是在初始化一个新变量作为参数sendCh的副本,这是一个空的chan chan time.Duration。所以我尝试了以下方法:

func doStuff(t time.Duration, ch <-chan chan time.Duration) {
  // What makes this different from the original code?
  ac := make(chan chan time.Duration)
  time.Sleep(t)
  ac <- t
}
// This gives an immediate error: cannot use t (type time.Duration) as type chan time.Duration in send

好的,那很有意义。我无法将time.Duration发送到time.Duration通道,我需要发送一个time.Duration通道。知道...但是我不知道原始代码为什么起作用,因为在我看来,除了原始的仅接收通道之外,这应该是相同的。因此,我导入了fmt并检查了ac的类型,并确定它是chan time.Duration。为什么?

我的最终实验是尝试将ac初始化为chan time.Duration直接导致死锁:

func doStuff(t time.Duration, ch <-chan chan time.Duration) {
  ac := make(chan time.Duration)
  time.Sleep(t)
  ac <- t
  // this causes deadlock
}

该死的哈哈...所以,总而言之,我不明白为什么在原始代码ac:= <-ch中将其初始化为时间通道。持续时间而不是时间通道time.Duration,我不明白为什么我在实验中所做的更改导致了它们所造成的不同错误情况。任何见解表示赞赏!

0 个答案:

没有答案