是否可以为函数boolInt
创建通道而无需重新定义它?
package main
func boolInt() (bool, int) {
return false, 1
}
func main() {
chanBool := make(chan bool)
chanInt := make(chan int)
go func() {
// chanBool <- boolInt() // error: multiple-value boolInt() in single-value context
chanBool, chanInt <- boolInt() // syntax error: unexpected semicolon or newline, expecting := or = or comma
}()
}
当我尝试在单值上下文中使用它时
chanBool <- boolInt()
我收到错误:multiple-value boolInt() in single-value context
。
在双价值背景下:
chanBool, chanInt <- boolInt()
收到错误:syntax error: unexpected semicolon or newline, expecting := or = or comma
。
答案 0 :(得分:6)
您想要将值发送到2个不同的频道。向频道发送值不是分配,因此您无法在一个步骤中发送这两个频道。
首先存储boolInt()
返回的值,然后将值发送到2个通道,如下所示:
go func() {
b, i := boolInt()
chanBool <- b
chanInt <- i
}()
测试:
go func() {
b, i := boolInt()
chanBool <- b
chanInt <- i
}()
fmt.Println("Received bool:", <-chanBool)
fmt.Println("Received int:", <-chanInt)
<强>输出:强>
Received bool: false
Received int: 1
注意:您首先必须从chanBool
收到,因为您创建了无缓冲的频道,并且因为在我们首先发送到chanBool
的示例中,它会阻止直到发送的值接收后才开始向chanInt
发送值。尝试首先从chanInt
接收会导致死锁("fatal error: all goroutines are asleep - deadlock!"
)。
如果要在频道上发送多个值,可以为值创建包装struct
:
type MyStruct struct {
b bool
i int
}
使用它:
ch := make(chan MyStruct)
go func() {
b, i := boolInt()
ch <- MyStruct{b, i}
}()
fmt.Println("Received value:", <-ch)
输出:
Received value: {false 1}
注意:您还可以使用[]interface{}
切片作为包装,但结构为其字段提供了更清晰的方式和类型安全。
注意#2:如果boolInt()
函数本身会返回MyStruct
值,这将使事情变得更容易和更清晰:
func boolInt() MyStruct {
return MyStruct{false, 1}
}
在这种情况下,代码就像这样简单:
ch := make(chan MyStruct)
go func() {
ch <- boolInt()
}()
另一种选择是制作频道类型interface{}
,以便它可以接收任何类型的值,并在其上发送/接收多个值:
ch := make(chan interface{})
go func() {
b, i := boolInt()
ch <- b
ch <- i
}()
fmt.Println("Received values:", <-ch, <-ch)
输出:
Received values: false 1
答案 1 :(得分:1)
如果要一起向通道发送两个值,一个选项是使用结构将两个值打包在一起。例如:
type BoolPlusInt struct {
B bool
I int
}
然后,您可以在将这两个值发送到频道之前创建此类型的值。例如:
c := make(chan BoolPlusInt)
go func() {
var v BoolPlusInt
v.B, v.I = boolInt()
c <- v
}()
如果您在频道上发送或接收多个goroutines,则此解决方案可能更为可取。由于这两个值打包在一起,您不必担心一个地方的错误导致两个通道不同步。
您可以在此处试验此建议:http://play.golang.org/p/I_Apg4ciFI