返回信息流先大概描述一下代码内容:main函数会调用GetAbc()这个函数,而GetAbc()会调用getCCC(),现在需要调用多次getCCC()函数,并给struct BBB对应的值进行赋值,有什么好的实现方法吗,以下是我的实现方法,但是肯定是不优美的[ema1],求大神讲解一下,有没有什么更好的方法,如果getCCC()需要返回多个值呢,比如error?
以下是代码:[ema23](如果代码有其它不优美的地方也请指出)
package test
import (
"encoding/json"
"fmt"
)
type AAA struct {
A uint64
B uint64
C string
}
type BBB struct {
T4 []*AAA
U4 []*AAA
T6 []*AAA
U6 []*AAA
}
func GetAbc() ([]uint8, error) {
var bbb BBB
c1 := make(chan []*AAA)
c2 := make(chan []*AAA)
c3 := make(chan []*AAA)
c4 := make(chan []*AAA)
go getCCC("tcp", true, c1)
go getCCC("udp", true, c2)
go getCCC("tcp6", true, c3)
go getCCC("udp6", true, c4)
bbb.T4 = <-c1
bbb.U4 = <-c2
bbb.T6 = <-c3
bbb.U6 = <-c4
netstatJSON, err := json.Marshal(bbb)
if err != nil {
return nil, err
}
return netstatJSON, nil
}
func getCCC(netType string, ipv4 bool, c chan []*AAA) {
var list []*AAA
list = append(list, parseFields(netType))
fmt.Println(netType)
c <- list
}
func parseFields(s string) *AAA {
tcp := new(AAA)
tcp.A = 1
tcp.B = 2
tcp.C = s
return tcp
}
这是一条镜像帖。来源:北邮人论坛 / golang / #656同步于 2016/10/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Golang机器人发帖
新手求教关于go多线程使用的问题
zhuzige
2016/10/21镜像同步14 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
如果是我就建一个buffer是4的channel,然后每个goroutine都往里塞,然后main循环取4次。
坐等大神
【 在 zhuzige 的大作中提到: 】
: 先大概描述一下代码内容:main函数会调用GetAbc()这个函数,而GetAbc()会调用getCCC(),现在需要调用多次getCCC()函数,并给struct BBB对应的值进行赋值,有什么好的实现方法吗,以下是我的实现方法,但是肯定是不优美的,求大神讲解一下,有没有什么更好的方法,如果getCCC()需要返回多个值呢,比如error?
: 以下是代码:(如果代码有其它不优美的地方也请指出)
: package test
: ...................
如果循环取四次,问题是怎么根据取的数据分清它到底对应结构体的哪一项?
【 在 aiquestion (狼肿粉丝团|学习c++) 的大作中提到: 】
: 如果是我就建一个buffer是4的channel,然后每个goroutine都往里塞,然后main循环取4次。
: 坐等大神
用一个struct包一下。。。。
【 在 zhuzige 的大作中提到: 】
: 如果循环取四次,问题是怎么根据取的数据分清它到底对应结构体的哪一项?
假设非得并行调用getCCC
func GetAbc() ([]uint8, error) {
var bbb BBB
wg := &sync.WaitGroup{}
wg.Add(4)
go getCCC("tcp", true, wg, &bbb.T4)
go getCCC("udp", true, wg, &bbb.U4)
go getCCC("tcp6", true, wg, &bbb.T6)
go getCCC("udp6", true, wg, &bbb.U6)
wg.Wait()
netstatJSON, err := json.Marshal(bbb)
if err != nil {
return nil, err
}
return netstatJSON, nil
}
func getCCC(netType string, ipv4 bool, wg *sync.WaitGroup, receiver *[]*AAA) {
var list []*AAA
list = append(list, parseFields(netType))
fmt.Println(netType)
*receiver = list
wg.Done()
}
func parseFields(s string) *AAA {
tcp := new(AAA)
tcp.A = 1
tcp.B = 2
tcp.C = s
return tcp
}
另外如果考虑getCCC接口的易用性也可以这样
func GetAbc() ([]uint8, error) {
var bbb BBB
wg := &sync.WaitGroup{}
wg.Add(4)
go func(){
bbb.T4 = getCCC("tcp", true)
wg.Done()
}()
go func(){
bbb.U4 = getCCC("udp", true)
wg.Done()
}()
go func() {
bbb.T6 = getCCC("tcp6", true)
wg.Done()
}()
go func(){
bbb.U6 = getCCC("udp6", true)
wg.Done()
}()
wg.Wait()
netstatJSON, err := json.Marshal(bbb)
if err != nil {
return nil, err
}
return netstatJSON, nil
}
func getCCC(netType string, ipv4 bool) []*AAA{
var list []*AAA
list = append(list, parseFields(netType))
fmt.Println(netType)
return list
}
总觉得楼主的写法也没有哪里不妥。要是我的话,我也会创建4个channel分别接收。顶多用for循环。
如果语言有future或者promise,或许还可以更抽象一些。不过,既然go里channel是最基本的,这样写倒是也清楚。
但是我如果要调用十几个get CCC这种函数的话难道要建十几个channel吗……用for循环的话是不是没法区分哪个返回值属于哪个结构体中对应的项?我能不能加个类似flag之类的东西,在for里用select判断一下,就是不知道怎么同时返回和接收flag和c(channel),因为我想尽量用一个值表示,不想建那么多变量
【 在 nuanyangyang (暖羊羊) 的大作中提到: 】
: 总觉得楼主的写法也没有哪里不妥。要是我的话,我也会创建4个channel分别接收。顶多用for循环。
: 如果语言有future或者promise,或许还可以更抽象一些。不过,既然go里channel是最基本的,这样写倒是也清楚。
建10个channel也不是错。channel不贵,不怕多。
对Go不熟,但如果用C的话,我会这样做:
struct Foo {
struct Bar bar;
};
struct Bar { ...};
int main() {
Foo foo1, foo2, foo3, foo4;
int *bar_ptrs[4] = {&foo1.bar, &foo2.bar, &foo3.bar, &foo4.bar};
const char* names[] = {"one", "two", "three", "four"};
int i;
for (i = 0; i < 4; i++) {
make_and_set_field(names[i], bar_ptrs[i]);
}
}
这样,用两个平行的数组,就能把名字和域对应起来。Go语言应该支持tuple类型吧?不太熟。
【 在 inaadversity 的大作中提到: 】
: 另外如果考虑getCCC接口的易用性也可以这样
: [code=py]
: func GetAbc() ([]uint8, error) {
: ...................
谢谢~我试试~[ema23]