以下のコードは、.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)
}