我在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

那么做事的正确方法是什么?


json.NewEncoder(file)返回类型为*Encoder的对象。 因此,尝试编辑该行:

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

只需在行中编辑file .err

1
file. err = os.Create(ReduceName(fileName, JobNumber, r))

到代码中的file, err

我希望这能解决您面临的问题。