Ошибка Scopelint: использование переменной в области диапазона
В тестовой функции TestGetUID код обнаруживает ошибку, о которой сообщаетscopelint, которая предупреждает об ошибке используя переменную x из области диапазона внутри функциональных литералов.
Рассмотрите следующие строки кода:
for _, x := range tests {
t.Run(x.description, func(t *testing.T) {
client := fake.NewSimpleClientset(x.objs...)
actual := getUID(client, x.namespace)
assert.Equal(t, x.expected, actual)
})
}
Ошибка относится к этим строкам, поскольку x — это переменная цикла внутри цикла диапазона, перебирающего срез тестов. Scopelint обнаруживает, что x используется в литералах функции, передаваемых в t.Run(), что может привести к потенциальным проблемам, если литералы функции вызываются после возврата t.Run().
Причина и Лучшие практики
Проблема возникает из-за того, что компилятор не может гарантировать, что литералы функции, созданные и переданные в t.Run(), не будут вызываться после выхода из t.Run(). Если бы литералы функции были вызваны после возврата t.Run(), они бы ссылались на переменную x, которая могла быть перезаписана значением из последующей итерации цикла.
Go vet выводит это предупреждение на предотвратить такое непреднамеренное поведение, которое может привести к ошибкам или даже гонкам данных, если литералы функций выполняются одновременно в разных горутинах.
Рекомендуемая передовая практика в таких случаях — либо передать значение переменной цикла в функциональный литерал в качестве аргумента или для создания копии переменной цикла и ссылки на копию внутри функционального литерала. Поскольку подпись функционального литерала не может быть изменена, рекомендуемым решением является создание копии, например:
x2 := x
После объявления этой копии идентификатор x в Функциональный литерал будет относиться к локальной копии, а не к переменной цикла. Хотя присвоение копии того же имени может показаться запутанным, оно ясно указывает на намерение использовать копию.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3