使用两个 return args 为 func 创建 chan
Create chan for func with two return args
是否可以在不重新定义的情况下为函数 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
。
在 2 值上下文中:
chanBool, chanInt <- boolInt()
得到错误:syntax error: unexpected semicolon or newline, expecting := or = or comma
.
使用 2 个不同的渠道
您想将值发送到 2 个不同的通道。向通道发送值不是赋值,因此您不能一次在两个通道上发送。
首先存储由 boolInt()
编辑的值 return,然后像这样将值发送到 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()
函数本身 return 一个 MyStruct
值,事情会变得更容易和更清楚:
func boolInt() MyStruct {
return MyStruct{false, 1}
}
在这种情况下,代码会像这样简单:
ch := make(chan MyStruct)
go func() {
ch <- boolInt()
}()
替代 1 通道解决方案
另一种选择是将通道类型设置为 interface{}
以便它可以接收任何类型的值,并且只是 send/receive 多个值:
ch := make(chan interface{})
go func() {
b, i := boolInt()
ch <- b
ch <- i
}()
fmt.Println("Received values:", <-ch, <-ch)
输出:
Received values: false 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
是否可以在不重新定义的情况下为函数 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
。
在 2 值上下文中:
chanBool, chanInt <- boolInt()
得到错误:syntax error: unexpected semicolon or newline, expecting := or = or comma
.
使用 2 个不同的渠道
您想将值发送到 2 个不同的通道。向通道发送值不是赋值,因此您不能一次在两个通道上发送。
首先存储由 boolInt()
编辑的值 return,然后像这样将值发送到 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()
函数本身 return 一个 MyStruct
值,事情会变得更容易和更清楚:
func boolInt() MyStruct {
return MyStruct{false, 1}
}
在这种情况下,代码会像这样简单:
ch := make(chan MyStruct)
go func() {
ch <- boolInt()
}()
替代 1 通道解决方案
另一种选择是将通道类型设置为 interface{}
以便它可以接收任何类型的值,并且只是 send/receive 多个值:
ch := make(chan interface{})
go func() {
b, i := boolInt()
ch <- b
ch <- i
}()
fmt.Println("Received values:", <-ch, <-ch)
输出:
Received values: false 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