4

我已将我拥有的一些代码简化为一个小示例,用于测试调用的变量是否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应该返回false。为什么要value?返回 true 呢?

4

4 回答 4

2

您正在使用function. 这会扫描函数体并为您预先创建局部变量,初始化为 NONE。这就是为什么value? 'class-name变为真的(因为 NONE 是变量的合法值,与“未设置”的情况不同)。

如果您func改为使用,则两者都将返回 false。

于 2010-07-02T22:58:03.413 回答
1

在这里,我向您展示了两个不使用 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方法“在后台”实现局部变量,因此上述描述也适用于它生成的所有函数。

于 2010-07-17T11:51:15.987 回答
1

还有另一种方法,它避免使用 FUNC/LOCAL 并且仍然允许使用 FUNCTION。

那就是不使用 SET-WORD!为任务。而是在 LIT-WORD 上使用 SET 函数!

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?功能。但是,对 SET 的调用将class-name在全局环境中设置……而不是本地环境。

于 2010-07-25T22:28:55.803 回答
1

我认为function行为与func /local. 看看这些例子:

>> f: func [/x] [value? 'x]
>> f
== true

我没有给 x 任何价值,但它说它有一个价值。/local 相同

>> f: func [/local x] [value? 'x]
>> f
== true

因为当您将变量设为本地(或细化)时,这意味着您已经为它设置了一个值(这是无),这就是这样function做的。

于 2010-07-29T14:54:59.270 回答