Область определения функции и область значений: В чем разница между областью определения и областью значения функции?

Модульное тестирование

— использование переменной области диапазона `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 , эта копия будет скрывать переменную цикла. После приведенного выше короткого объявления переменной идентификатор

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) Элиф слово == ".

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *