我可以在 go 中使用 make(chan someStruct) 吗?

Can I use make(chan someStruct) in go?

例如:

type name struct {
    name string
    age int
}

func main() {
      c := make(chan name)

      c <- name{"sfsaf", 1}
      a, b := <- c

      close(c)
}

结果:

fatal error: all goroutines are asleep - deadlock!

我想通过通道传递值。我该怎么办?

是的,你可以传递结构。但这不是您的 OP 中的问题。

当没有接收器准备接收时,您在通道上发送了一个值。这就是导致你陷入僵局的原因。

通道预计 receiver 会阻塞,等待 sender。这是通过 Goroutines 完成的。

因此,将您的发送者包装在一个不会立即执行的 goroutine 中。

package main

import (
    "fmt"
)

type name struct {
    name string
    age  int
}

func main() {
    c := make(chan name)

    go func() {
        c <- name{"sfsaf", 1}
        close(c)
    }()

    for n := range c {
        fmt.Println(n)
    }

    fmt.Println("channel was closed (all done!).")
}

在操场上看到它:https://play.golang.org/p/uaSuCaB4Ms

这是可行的,因为发送方的 goroutine 还没有执行。直到当前执行的 goroutine 被阻塞。

我们在 for n := range c 循环中被阻塞了。这是接收者,坐着等待值。 (使用 for 循环迭代通道值是一种常见的模式,因为它会坐下来等待值)。

现在我们在 for 循环中被阻塞等待接收值,内联 gorouting 现在将执行,以在通道上发送我们的值。

此外,我们遵循安全做法并在我们自己和 close(c) 之后清理通道,发出 for 循环或 select 声明将不再发送任何值的信号。 发送者总是关闭,接收者从不关闭。这是 for 范围循环用于退出 for 循环并继续执行其余代码的模式。


附带说明一下,您通过传递结构的值而不是指针做得很好。

如果传递指针,则必须在对象周围实施一些互斥锁以防止 R/W 恐慌。

Do not communicate by sharing memory; instead, share memory by communicating.

围绕您的通道和 goroutine 坚持传递值,而不是指针,并从中获益。