我在Golang很新,遇到以下问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // XXX a bit inefficient. could open r files and run over list once for r := 0; r < nreduce; r++ { file, err = os.Create(ReduceName(fileName, JobNumber, r)) if err != nil { log.Fatal("DoMap: create", err) } enc := json.NewEncoder(file) for e := res.Front(); e != nil; e = e.Next() { kv := e.Value.(KeyValue) if ihash(kv.Key)%uint32(nreduce) == uint32(r) { err := enc.Encode(&kv) if err != nil { log.Fatal("DoMap: marshall", err) } } } file.Close() } |
基本上,此代码段在每个for循环迭代中创建一个文件,然后根据(键,值)对打开一个文件,对属于该文件的内容进行编码。 但是,此代码效率低下,因为它扫描该文件的次数过多。 这样做的更有效方法是打开r文件并在该列表文件上运行一次。 所以我想这样写(但我不知道该怎么做):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | enc_map := make(map[int]*Encode) for r := 0; r < nreduce; r++ { file. err = os.Create(ReduceName(fileName, JobNumber, r)) if err != nil { log.Fatal("DoMap: create", err) } enc := json.NewEncoder(file) enc_map[r] = enc for e := res.Front(); e != nil; e = e.Next() { kv := e.Value.(KeyValue) r := ihash(kv.Key)&uint32(nreduce) err := enc_map[r].Encode(&kv) if err != nil { log.Fatal("DoMap: marshall", err) } } |
此代码段首先创建一个保存json.Encoder对象的映射,然后对该文件进行一次迭代。 我查阅了go文档,并说json.Encoder的类型名称是* Encode。 但是线
1 | enc_map := make(map[int]*Encode) |
是错误的,编译器给我以下错误:
1 2 3 | ../mapreduce/mapreduce.go:228: undefined: Encode ../mapreduce/mapreduce.go:230: file.err undefined (type *os.File has no field or method err) ../mapreduce/mapreduce.go:230: multiple-value os.Create() in single-value context |
那么做事的正确方法是什么?
1 | enc_map := make(map[int]*Encode) |
至:
1 | enc_map := make(map[int]* json.Encoder) |
消除错误:
1 | ../mapreduce/mapreduce.go:228: undefined: Encode |
为了摆脱其他2个错误,即
1 2 | ../mapreduce/mapreduce.go:230: file.err undefined (type *os.File has no field or method err) ../mapreduce/mapreduce.go:230: multiple-value os.Create() in single-value context |
只需在行中编辑
1 | file. err = os.Create(ReduceName(fileName, JobNumber, r)) |
到代码中的
我希望这能解决您面临的问题。