Нужен ли второй defer file.Close(), после перезаписи переменной?
Например, есть такой код:
jsonFile, err := os.Open("referenceData/ex.json")
if err != nil {
return err
}
defer jsonFile.Close() // первый defer
byteValue, err := ioutil.ReadAll(jsonFile)
if err != nil {
return err
}
err = json.Unmarshal(byteValue, &exToParse)
if err != nil {
return err
}
jsonFile, err = os.Open("referenceData/di.json") // перезапись jsonFile
if err != nil {
return err
}
defer jsonFile.Close() // нужно ли заново объявлять defer jsonFile.Close()?
byteValue, err = ioutil.ReadAll(jsonFile)
if err != nil {
return err
}
err = json.Unmarshal(byteValue, &diToParse)
if err != nil {
return err
}
Сначала инициализирую переменную не через var, а сразу передаю значение. Потом сразу пишу defer jsonFile.Close()
Потом в этот же файл загружаю другой json, и так же пишу defer jsonFile.Close().
Вопрос - а нужен ли второй defer? По идеи в ОЗУ, после перезаписи, jsonFile один и тоже, с тем же адресом, но только с другим содержанием.
Ответы (1 шт):
Автор решения: Ainar-G
→ Ссылка
Да, нужен, так как аргументы функции, вызываемой
defer, вычисляются в момент использования
defer. Можете увидеть в подобном
простом примере:
type T int
func (t T) Close() { fmt.Println(int(t)) }
// …
t := T(1)
defer t.Close()
t = T(2)
defer t.Close()
2 1
И вообще не рекомендую переиспользовать переменные подобным образом, так как это усложняет понимание текста программы.
Ну и вдогонку. Не так:
b, err := ioutil.ReadAll(r)
// Check err.
err = json.Unmarshal(b, &v)
// Check err.
А так:
err = json.NewDecoder(r).Decode(&v)
// Check err.