Изменение глобальной переменной
К каким негативным последствиям может привести данный фрагмент кода, и как это исправить? Приведите корректный пример реализации.
var justString string
func someFunc() {
v := createHugeString(1 << 10)
justString = v[:100]
}
func main() {
someFunc()
}
Это учебное задание, не могу понять конкретную проблему. 1) Изменение глобальной переменной в функции может быть неожиданным? 2) Переменная созданная на стеке и потом положенная в глобальную переменную приведет к каким-то ошибкам? Предполагаю, что корректная реализация выглядит вот так:
func someFunc() {
justString = createHugeString(100)
}
или
func someFunc() {
justString = createHugeString(1 << 10)[:100]
}
Но почему так могло бы быть лучше не знаю.
Ответы (1 шт):
Вероятно, вы не очень поняли своё задание. Здесь приведен пример работы с очень большими строками, которые могут не поместиться в памяти. Да и работа с ними будет не быстрая.
Такую строку можно, например, записывать в файл и читать по мере необходимости:
func someFunc() {
f, err := os.Create("huge_string.txt")
if err != nil {
panic(err)
}
defer f.Close()
_, err = createHugeString(1 << 30, f) // Передаем файл в качестве io.Writer, чтобы записать строку в него
}
Ещё один момент - строки в Go иммутабельны, то есть когда мы их изменяем, фактически создаём новую строку. Поэтому, если мы хотим изменить строку, то лучше использовать []byte:
func someFunc() {
b := []byte(createHugeString(1 << 30))
b = b[:100]
}
Если же говорить только про глобальные переменные, абстрагируясь от задания, то оба ваших предположения верны:
К глобальным переменным можно обращаться из любой функции, поэтому их изменение может быть неожиданным. Такое поведение может привести к ошибкам, которые очень сложно отлаживать. На самом деле, глобальные переменные допустимы, но их использование должно быть оправдано. Например, в некоторых случаях они могут быть полезны для конфигурации приложения, но в большинстве случаев лучше использовать локальные переменные.
Локальные переменные создаются на стеке, а глобальные - на куче. Работа со стеком быстрее, чем с кучей, поэтому лучше использовать локальные переменные, если это возможно.
Приведенная вами "корректная реализация" не совсем корректна. Вы просто избавились от промежуточной переменной v, но проблема была не в ней. Избавляться нужно было от глобальной переменной justString. И в таком случае результат работы функции нужно вернуть, иначе он просто потеряется после завершения работы функции someFunc():
func someFunc() string {
return createHugeString(1 << 10)[:100]
}