: = оператор и если утверждение в Голанге

Следующее работает как функция для открытия файла

func openFile(filename string) {
  var file *os.File
  var err error
  if file, err = os.Open(filename); err != nil {
    log.Printf("Failed to open the file: %s.", filename)
    return
  }
  defer file.Close()
  // blahblahblah
}

однако это не работает, когда я пытаюсь использовать: = для объявления файла переменной

func updateFrequencies(filename string, frequencyForWord map[string]int) {
  if file, err := os.Open(filename); err != nil {
     ....
  }
}

error:./word_frequencies_2.go:30: undefined: файл

Но если бы я немного изменил это, это работает

file, err := os.Open(filename)
if err != nil {
   log.Printf("Failed to open the file: %s.", filename)
   return
}

почему я не могу использовать: = как часть инструкции if?

Ответ 1

Почему я не могу использовать: = как часть инструкции if?

Вы можете, но тогда переменные определены в области if. Таким образом, file не определяется вне вашего блока if.

То же правило применяется к определениям в for, switch и аналогичных блоках.

Ответ 2

Mostafa уже указал, что переменная file не определена из блока if, и вы уже видели, как это исправить.

Но у вашей функции есть еще две важные проблемы.

Первый заключается в том, что он ничего не возвращает.

Вы можете исправить это, изменив его на

func openFile(filename string) *os.File, error {
     ... implementation
     return file, nil
}

Но это позволило бы другому: когда ваша функция закончится, он закрывает файл из-за defer file.Close(), чтобы пользователь этой функции получал закрытый файл. Правда в том, что ваша функция не имеет особого смысла. Вы можете исправить это, разрешив ему пройти обратный вызов, который будет использовать этот файл, или разрешив пользователю закрыть файл, но нужно сделать прямо, чтобы открыть файл там, где он вам нужен.