— использование переменной области диапазона `x` в функциональном литерале (scopelint)
спросил
Изменено 1 год, 6 месяцев назад
Просмотрено 3к раз
функция TestGetUID(t *testing.T) { пространство имен := "lkfm" ожидаемый идентификатор: = "fake_uid" вар тесты = [] структура { строка описания ожидаемая строка строка пространства имен objs []runtime.Object }{ {"PositiveScenario", expectuid, namespace, []runtime.Object{simpleNamespace(namespace)}}, } для _, x := тесты диапазона { t.Run(x.description, func(t *testing.T) { клиент: = подделка.NewSimpleClientset(x.objs...) фактический: = getUID (клиент, x. namespace) assert.Equal(t, x.ожидаемый, фактический) }) } }
Lint дает мне некоторую проблему:
- client := fake.NewSimpleClientset(x.objs…)
- факт: = getUID (клиент, x.namespace)
- assert.Equal(t, x.ожидаемый, фактический)
, и он сообщает об этой ошибке: « Использование переменной в области диапазона x
в функциональном литерале (scopelint) »
- модульное тестирование
- go
4
х
— это переменная цикла, которая повторно используется на каждой итерации. И вы создаете литерал функции, который вы передаете t.Run()
. Компилятор не знает (не имеет гарантии), не вызывается ли созданный и переданный функциональный литерал после возврата t.Run()
, и в этом случае функциональный литерал будет ссылаться на переменную цикла, которая будет перезаписана значением следующей итерации.
Итак, go vet
предупреждает о таком использовании.
Часто решение состоит в том, чтобы передать значение переменной цикла в литерал функции в качестве аргумента или создать копию переменной цикла и обратиться к этой копии. Поскольку сигнатура литерала вашей функции фиксирована (вы не можете ее изменить), создайте копию переменной, например:
x2 := x
И обратитесь к x2
внутри литерала функции. Это сделает счастливым.
Кроме того, поскольку намерение сделать копию ясно, вы можете использовать то же имя, например. x := x
, эта копия будет скрывать переменную цикла. После приведенного выше короткого объявления переменной идентификатор
будет ссылаться на локальную копию (а не на переменную цикла). В целом это может вызвать путаницу, но здесь намерение ясно и приемлемо.
0
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почтаТребуется, но не отображается
python - Функциональные переменные: каков диапазон области действия функции
Недавно я работал над игрой слов в python, тем не менее у меня возникли проблемы с небольшими деталями. Идея игры состоит в том, чтобы создавать слова с буквами в рука дана случайным образом. Функция, которая координирует игру, просит пользователя ввести букву и в соответствии с ней позволяет ему сыграть новую руку, снова сыграть ту же руку или выйти из игры. Проблема в том, что я не могу заставить игру вернуться к предыдущей раздаче и позволить пользователю снова сыграть в нее. Вместо этого код возвращает измененную версию предыдущей руки, так что если вы ввели слово правильно, букв в этом слове не будет. Я думал, что это невозможно, так как функция, которая «обновляет руку», лежит в другой области. Я работаю на питоне 3.2.1
Я разместил весь код, чтобы вы могли протестировать его и посмотреть, что он делает. Проблема, однако, заключается в функциях: play_game, play_hand и update_hand.
случайный импорт строка импорта ГЛАСНЫЕ = 'aeiou' СОГЛАСНЫЕ = 'bcdfghjklmnpqrstvwxyz' РУЧНОЙ_РАЗМЕР = 7 SCRABBLE_LETTER_VALUES = { «а»: 1, «б»: 3, «с»: 3, «г»: 2, «е»: 1, «е»: 4, «г»: 2, «ч»: 4, «и ': 1, 'j': 8, 'k': 5, 'l': 1, 'm': 3, 'n': 1, 'o': 1, 'p': 3, 'q': 10, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 4, 'w': 4, 'x': 8, 'y': 4, 'з': 10 } WORDLIST_FILENAME = "words. txt" деф load_words(): """ Возвращает список допустимых слов. Слова представляют собой строки строчных букв. В зависимости от размера списка слов эта функция может занять некоторое время, чтобы закончить. """ print("Загрузка списка слов из файла...") # inFile: файл inFile = открыть (WORDLIST_FILENAME, 'r') # список слов: список строк список слов = [] для строки в inFile: список слов.добавление(строка.полоса().нижний()) print(" ", len(wordlist), "слова загружены.") вернуть список слов защита get_frequency_dict (последовательность): """ Возвращает словарь, в котором ключи являются элементами последовательности а значения представляют собой целые числа для количества раз, элемент повторяется в последовательности. последовательность: строка или список возврат: словарь """ # частоты: словарь (element_type -> int) частота = {} для x последовательно: частота[х] = частота.получить(х,0) + 1 частота возврата def get_word_score (слово, n): """ Возвращает оценку за слово.Предполагает, что слово является допустимое слово. Оценка за слово – это сумма баллов за буквы. в слове, умноженное на длину слова, плюс 50 баллов, если все n букв используются с первого раза. Буквы оцениваются как в Scrabble; А стоит 1, Б стоит стоит 3, C стоит 3, D стоит 2, E стоит 1 и так далее. слово: строка (строчные буквы) возвращает: целое >= 0 """ оценка = 0 для символа в слове: оценка = оценка + (SCRABBLE_LETTER_VALUES[символ]) оценка = оценка * длина (слово) если len(слово) == 7: оценка = оценка + 50 обратный счет защита display_hand (рука): """ Отображает буквы, находящиеся в данный момент в руке. Например: display_hand({'a':1, 'x':2, 'l':3, 'e':1}) Должен распечатать что-то вроде: а х х л л е Порядок букв не важен. рука: словарь (строка -> int) """ для письма в руке.keys(): для j в диапазоне (рука [буква]): печатать (письмо,) Деф сделка_рука (n): """ Возвращает случайную комбинацию из n строчных букв. Не менее n/3 букв в руке должны быть ГЛАСНЫМИ. Руки представлены в виде словарей. Ключи буквы, а значения - это количество раз, конкретная буква повторяется в этой руке. п: целое >= 0 возвращает: словарь (строка -> int) """ рука={} число_гласных = целое (n / 3) для i в диапазоне (num_vowels): x = ГЛАСНЫЕ [random.randrange (0, len (ГЛАСНЫЕ))] рука[х] = рука.получить(х, 0) + 1 для i в диапазоне (num_vowels, n): x = СОГЛАСНЫЕ [случайные.randrange (0, len (СОГЛАСНЫЕ))] рука[х] = рука.получить(х, 0) + 1 ответная рука def update_hand (рука, слово): """ Предполагается, что слово «рука» содержит все буквы слова. Другими словами, это предполагает, что сколько бы раз буква появляется в «слове», «рука» имеет по крайней мере как многие из этого письма в нем. Обновляет руку: использует буквы в данном слове и возвращает новую руку, без этих букв в ней. Не имеет побочных эффектов: не модифицирует руку.слово: строка рука: словарь (строка -> int) возвращает: словарь (строка -> int) """ для я в слове: new_hand = рука new_VOWELS = ГЛАСНЫЕ new_CONSONANTS = СОГЛАСНЫЕ если я в ГЛАСНЫХ: new_VOWELS = new_VOWELS.replace("i", "") new_hand[i] = new_hand.get(i, 0) - 1 если new_hand[i] <= 0: new_hand.pop(i, нет) еще: new_CONSONANTS = new_CONSONANTS.replace("i", "") new_hand[i] = new_hand.get(i, 0) - 1 если new_hand[i] <= 0: new_hand.pop(i, нет) возврат (new_hand) def is_valid_word(слово, рука, список_слов): """ Возвращает True, если слово находится в списке слов и полностью состоит из букв в руке. В противном случае возвращает False. Не изменяет hand или word_list. слово: строка рука: словарь (строка -> int) word_list: список строчных строк """ для символа в слове: х = 0 если персонаж в руке: х = х + 1 если (x==(len(word)-1)) и (слово в word_list): возврат (правда) еще: возврат (ложь) def calculate_handlen (рука): хэндлен = 0 для v в hand. values(): хэндлен += v вернуть хэндлен def play_hand (рука, список_слов): """ Позволяет пользователю разыграть данную руку следующим образом: * Рука отображается. * Пользователь может ввести слово. * Недопустимое слово отклоняется, и отображается сообщение с запросом пользователю выбрать другое слово. * Когда введено действительное слово, оно использует буквы от руки. * После каждого допустимого слова: отображается счет за это слово, отображаются оставшиеся буквы в руке, и пользователь просят ввести другое слово. * Сумма очков слов отображается, когда рука заканчивается. * Рука заканчивается, когда не остается неиспользованных букв. Пользователь также может закончить разыгрывание руки, введя одну точка (строка '.') вместо слова. рука: словарь (строка -> int) word_list: список строчных строк """ оценка = 0 хан = рука пока верно: print("Оценка= ", оценка) word = str(input("Введите слово: ")) значение = is_valid_word(слово, хан, список_слов) если значение == Истина: print("Поздравляем, это слово стоит", get_word_score(word, 7), "баллов") print ("Пожалуйста, введите другое слово") хан = update_hand (хан, слово) print("Текущая рука=") display_hand (хан) оценка = оценка + get_word_score (слово, 7) Элиф слово == ".