Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在结构中使用映射的更好方法?Go编程语言练习1.4_Go_Struct - Fatal编程技术网

在结构中使用映射的更好方法?Go编程语言练习1.4

在结构中使用映射的更好方法?Go编程语言练习1.4,go,struct,Go,Struct,我正在学习Go编程语言的练习1.4。程序读取stdin或作为参数给定的文件,并输出具有重复项的行 我有工作代码,我只是想知道是否有更好的方法在结构中使用映射?现在我在结构中创建了一个新的映射,当找到唯一的行时。但这看起来很笨拙,我想知道我是否应该用另一种方式来处理这个问题 type dupCount struct { count int fileCount map[string]int } func main() { counts := make

我正在学习Go编程语言的练习1.4。程序读取stdin或作为参数给定的文件,并输出具有重复项的行

我有工作代码,我只是想知道是否有更好的方法在结构中使用映射?现在我在结构中创建了一个新的映射,当找到唯一的行时。但这看起来很笨拙,我想知道我是否应该用另一种方式来处理这个问题

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\n", 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
        }
}

我在countLines中使用tmp变量来解决无法直接为地图中的值赋值的问题。

我不认为它特别凌乱,但我可能会尝试使用某种
addDupe
helper函数,该函数按值取
dupCount
,进行添加行所需的任何更改,并按值返回
dupCount

func addDupe(dupes dupCount, filename string) dupCount {
    if dupes.count == 0 {
        dupes.fileCount = make(map[string]int)
    }
    dupes.fileCount[filename]++
    dupes.count++
    return dupes
}
这类似于切片的标准
append
函数的工作方式。然后,
countLines
可以写成:

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)
    }
}

但是我所做的就是用一个函数参数替换
tmp

在使用
fileCount
映射之前,必须先创建它,这样我就不会觉得这太混乱了。顺便说一下,您可以通过将
counts
声明为
map[string]*dupCount
来简化此过程。这样,您就不必从地图中读取值,然后在最后将其放回地图。您需要处理一个指针,因此可以直接修改字段。@AndySchweig我不确定这是否会使它更简单。然后必须检查指针是否为nil,并在这种情况下显式创建一个
dupCount