下面的代码打开一个 .txt 文件并计算词频。我正在关注一本书,但我感到困惑:


我的问题在这里:


filename := os.Args[1]

frequencyForWord := map[string]int{}

updateFrequencies(filename, frequencyForWord)

fmt.Println(frequencyForWord)

我创建了一个名为的变量frequencyForWord并将其传递给一个不返回任何调用的函数func updateFrequencies


这个函数修改了变量,这就是为什么当我这样做时,fmt.Println(frequencyForWord)它向我展示了一个以单词作为键和它们的计数作为值的映射。


我的问题是:


为什么我不必做这样的事情


frequencyForWord = updateFrequencies(filename, frequencyForWord)

fmt.Println(frequencyForWord)

// And then change func updateFrequencies to something to returns a map

我想为了让函数修改变量,我需要像这样传入变量作为引用 updateFrequencies(filename, &frequencyForWord)


原始代码:


package main


import(

"fmt"

"path/filepath"

"os"

"log"

"bufio"

"strings"

"unicode"

)


func main() {

  if len(os.Args) == 1 || os.Args[1] == "-h" {

    fmt.Printf("usage: %s <file>\n", filepath.Base(os.Args[0]))

    os.Exit(1)

  }

  filename := os.Args[1]

  frequencyForWord := map[string]int{}

  updateFrequencies(filename, frequencyForWord)

  fmt.Println(frequencyForWord)

}




func updateFrequencies(filename string, frequencyForWord map[string]int) string {

  file, err := os.Open(filename)

  if err != nil {

    log.Printf("Failed to open the file: %s.", filename)

  }

  defer file.Close()

  readAndUpdateFrequencies(bufio.NewScanner(file), frequencyForWord)

}


func readAndUpdateFrequencies(scanner *bufio.Scanner, frequencyForWord map[string]int) {

  for scanner.Scan() {

    for _, word := range SplitOnNonLetter(strings.TrimSpace(scanner.Text())) {

      frequencyForWord[strings.ToLower(word)] += 1

    }

  }


  if err := scanner.Err(); err != nil {

    log.Fatal(err)

  }

}


func SplitOnNonLetter(line string) []string {

  nonLetter := func(char rune) bool { return !unicode.IsLetter(char) }

  return strings.FieldsFunc(line, nonLetter)

}