Как значение? Функция работает?
Вопрос
Я сократился до небольшого примера некоторых кода, который у меня есть, которые у меня есть, которые проверяют ли переменную class-name
имеет значение, назначенное ему:
ask-params: function [
config-file [file!]
default-class-name
default-fields
] [
probe value? 'class-name
input
either (value? 'class-name) [
probe class-name
] [
;-- omit code in this branch for now
]
]
ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name"
Выражение value? 'class-name
Возвращает false здесь. С другой стороны, если я заполняю пропавшую ветку с заданием:
ask-params: function [
config-file [file!]
default-class-name
default-fields
] [
probe value? 'class-name
input
either (value? 'class-name) [
probe class-name
] [
class-name: default-class-name
]
]
ret-block: ask-params %simple-class.params.txt "Person" "First Name, Last Name"
Это вернется правда для value? 'class-name
. Отказ Но в этом втором случае, class-name: default-class-name
даже даже не выполняется.
Я думаю, что имя класса не должно существовать в памяти, так value? 'class-name
следует возвращать ложь. Почему value?
Вместо этого возвращается?
Решение
Ты используешь function
. Отказ Это сканирует тело функции и предварительно создает локальные переменные для вас, инициализированные ни на что. Поэтому value? 'class-name
становится правдой (потому что никто не является юридической ценностью для переменной, отличной от ситуации «unset»).
Если вы использовали func
Вместо этого они оба вернут ложь.
Другие советы
Я не думаю function
ведет себя иначе, чем func /local
. Отказ Посмотрите на эти примеры:
>> f: func [/x] [value? 'x]
>> f
== true
Я не давал никакой ценности X, но он говорит, что имеет значение. То же самое для / местный
>> f: func [/local x] [value? 'x]
>> f
== true
Потому что когда вы делаете переменную локальную (или уточнение), то это означает, что вы уже устанавливаете значение для него значение (что нет), и это то, что function
делает.
Здесь я покажу вам два примера, не используя функцию, но в противном случае эквивалентно вашему коду:
ask-params: func [config-file [file!] default-class-name default-fields] [
probe value? 'class-name
input
either (value? 'class-name) [
probe class-name
][
]
]
ask-params: func [
config-file [file!] default-class-name default-fields /local class-name
] [
probe value? 'class-name
input
either (value? 'class-name) [
probe class-name
][
]
]
В то время как value?
Функция в первом примере дает #[false]
, во втором примере это дает #[true]
. Отказ Это связано с тем, что «аргументы уточнения» после «неиспользованного уточнения» (уточнение, которое не используется в фактическом вызове), инициализированы с #[none!]
вместе с переменной утонченности. Это относится к /local
переменные, а также /local
Уточнение не отличается от других уточнений функций (за исключением того, что это соглашение использовать его для определения локальных переменных).
Поскольку function
Генератор использует /local
Способ реализации локальных переменных «Под капотом» приведенное выше описание применяется ко всем функциям, которые он также генерирует.
Есть еще один способ, который позволяет избежать использования Func / Local и до сих пор позволяет использовать функцию.
Это не использовать Set-Word! для назначения. Вместо этого используйте функцию SET в Lit-Word!
ask-params: function [config-file [file!] default-class-name default-fields] [
probe value? 'class-name
input
either (value? 'class-name) [
probe class-name
] [
set 'class-name default-class-name
]
]
Ты получишь #[false]
для value?
функция. Тем не менее, вызов для установки будет установлен class-name
В глобальной среде ... не как местное.