Вопрос

Я сократился до небольшого примера некоторых кода, который у меня есть, которые у меня есть, которые проверяют ли переменную 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 В глобальной среде ... не как местное.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top