Октава: я не могу изменить значение глобальной переменной после ее очистки

Я определил глобальную переменную global x=-2. После создания глобальные переменные нельзя переназначить, т. е. x=7 не изменит -2 значение x. По этой причине я очищаю переменную.

>> clear x

Я проверяю, что переменная больше не существует.

>> exist("x")
ans = 0

Но когда я снова создаю глобальную переменную с новым значением, например, global x=7, я получаю глобальную переменную в старом значении.

>> global x=7
>> x
   x = -2

Почему это происходит? Переменная x действительно не удалена?


person loved.by.Jesus    schedule 22.02.2016    source источник


Ответы (2)


То, что вы видите, является ожидаемым поведением. Это выглядит странно, но рассмотрим следующий пример:

global x = 5;

function say_x ()
  global x = 3;
  disp (x);
endfunction

say_x ();
x = 7;
say_x ();

Что возвращает:

5
7

Обратите внимание, что вам нужно объявить x внутри функций для доступа к глобальной переменной. Также обратите внимание, что присвоение ему значения 3 не работает. Причина в том, что такие строки, как persistent x = 3 или global x = 3, оцениваются только в первый раз. Это означает, что когда вы вызываете say_x(), x уже имеет значение, поэтому ему никогда не присваивается значение 3 (правая часть даже не оценивается).

В настоящее время; к вашей фактической проблеме, которая заключается в том, что все это происходит в таблице main/base namespace/symbol, перепутанной с тем, что должен делать clear(). Вы запускаете это:

global x = 1;
clear x;
global x = 2;
x # you are surprised that x is 1 instead of 2

Во-первых, обратите внимание, что clear() на самом деле не очищает значения переменных. Это удалит их имена из таблицы символов. Обратите внимание на текст справки от clear():

-- Command: clear [options] pattern ...
    Delete the names matching the given patterns from the symbol table.

С «обычными» переменными имена не будут больше нигде, и вы эффективно удалите их значение. Но это не так с глобальными переменными. Их значения останутся где-то, готовые стать доступными в следующий раз, когда будет определена глобальная переменная с их именем.

Что происходит, когда вы пытаетесь снова определить x, так это то, что это имя уже существует в таблице символов глобальных переменных. Таким образом, вы возвращаете его в текущую таблицу символов (точно так же, как это происходит внутри функции), а правая часть (= 2) никогда не оценивается.

Как вы уже выяснили, чтобы действительно удалить имена из глобальной таблицы символов, вам нужно использовать clear -global (как описано в тексте справки clear).

person carandraug    schedule 22.02.2016

Нам нужно использовать параметр -global, чтобы эффективно удалить глобальную переменную: clear -global x

Пример:

>> global x=-2
>> clear -global x
>> exist("x")
ans = 0
>> global x=7
>> x
   x = 7

Это должно быть ошибка в Octave, потому что одна только команда clear похоже работает нормально, очищая глобальную переменную: нет сообщения об ошибке, а проверка "exist" выводит ожидаемое.

(Надеюсь, это поможет, мне потребовалось несколько минут, чтобы найти решение;))

person loved.by.Jesus    schedule 22.02.2016
comment
Это не ошибка. Вы путаете удаление значений с удалением имени из таблицы символов (clear() делает это позже). Хотя они часто совпадают, это не относится к глобальным переменным. - person carandraug; 22.02.2016