猿问

golang中的变量修改【可变性】

下面的代码打开一个 .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)

}



陪伴而非守候
浏览 266回答 2
2回答

侃侃尔雅

因为地图结构本身不包含值,而是指向保存值的结构。正如文档中所写:像切片一样,映射保存对底层数据结构的引用。如果您将地图传递给更改地图内容的函数,则更改将在调用方中可见。这就像你传递一个指向函数的指针一样:它让函数改变你的值。这是相同现象的另一个例子:type A struct {&nbsp; &nbsp; b *B}type B struct {&nbsp; &nbsp; c int}&nbsp;func incr(a A) {&nbsp; &nbsp; a.b.c++}func main() {&nbsp; &nbsp; a := A{}&nbsp; &nbsp; a.b = new(B)&nbsp; &nbsp; fmt.Println(a.b.c) // prints 0&nbsp; &nbsp; incr(a)&nbsp; &nbsp; fmt.Println(a.b.c) // prints 1}
随时随地看视频慕课网APP

相关分类

Go
我要回答