在结构中使用地图的更好方法? 参加编程语言练习1.4

I'm working on Exercise 1.4 from The Go Programming Language. The program reads stdin or files given as arguments and outputs lines that have duplicates.

I have working code, I'm just wondering if there is a better way to use maps within structs? Right now I have a new map being made in the struct when a unique line is found. But it seems clumsy, and I want to know if I should approach this another way.

type dupCount struct {
        count int
        fileCount map[string]int
}

func main() {
        counts := make(map[string]dupCount)
        files := os.Args[1:]
        if len(files) == 0 {
                countLines(os.Stdin, counts, "stdin")
        } else {
                for _, arg := range files {
                        f, err := os.Open(arg)
                        if err != nil {
                                fmt.Fprintf(os.Stderr, "dup2: %v
", err)
                                continue
                        }
                        countLines(f, counts, arg)
                        f.Close()
                }
        }
func countLines(f *os.File, counts map[string]dupCount, filename string) {
        input := bufio.NewScanner(f)
        for input.Scan() {
                var tmp = counts[input.Text()]
                if tmp.count == 0 {
                        tmp.fileCount = make(map[string]int)
                }
                tmp.count++
                tmp.fileCount[filename]++
                counts[input.Text()] = tmp
        }
}

I am using the tmp variable in countLines to get around the inability to assign directly to values in maps as outlined in the Go Github repo.

I don't think it is particularly messy but I might be tempted to make some sort of addDupe helper function that takes a dupCount by value, makes whatever changes are required to add the line and returns the dupCount by value

func addDupe(dupes dupCount, filename string) dupCount {
    if dupes.count == 0 {
        dupes.fileCount = make(map[string]int)
    }
    dupes.fileCount[filename]++
    dupes.count++
    return dupes
}

This is similar to the way the standard append function for slices works. Then countLines can be written as:

func countLines(r io.Reader, counts map[string]dupCount, filename string) {
    input := bufio.NewScanner(r)
    for input.Scan() {
        line := input.Text()
        counts[line] = addDupe(counts[line], filename)
    }
}

But all I have done is replace your tmp with a function parameter.