2

在 Rebol 2 中有一个 HASH!类型以及地图!类型。FIND 和 SELECT 函数以及基于路径的选择都支持这两者:

>> m: to map! [someKey someValue]
== make hash! [someKey someValue]

>> m/someKey
== someValue

>> select m 'someKey
== someValue

要检测键不在地图中,您可以使用 FIND 并针对 NONE 进行测试

>> find m 'someOtherKey
== none

但是在这种情况下,基于路径的选择会出错:

>> m/someOtherKey
** Script Error: Invalid path value: someOtherKey
** Near: m/someOtherKey

另一方面,Rebol 3 只有 MAP!。但是 FIND和 SELECT只支持系列类型和 MAP!不再被认为是一个系列。我看到(?)与地图交互的唯一方法是通过路径选择,这在非会员情况下不会引发错误:

>> m/someOtherKey
== none

...如果您的密钥在变量(或字符串)中,则必须使用 PAREN!

>> var: 'someKey
== someKey

>> m/(var)
== someValue

这在 Rebol 2 中也有效,但同样需要注意的是,当您请求不存在的东西时,会抛出错误而不是返回 NONE。

因此,如果我做对了,路径选择是从 Rebol 2 和 3 中的键中检索值的“常见”方式。尽管如此,我没有看到一种常见的测试缺乏成员资格的方式。如何处理这个?

4

1 回答 1

3

需要注意的三点:

  1. 最直接与您的问题有关:select在 Rebol 3 中也可以正常工作,如下面的交互所示:

    >> system/version
    == 2.100.111.4.4  ; That's Rebol 3 A111.
    
    >> m: map [a 1 b 2 c 3]
    == make map! [
        a 1
        b 2
        c 3
    ]
    
    >> select m 'b
    == 2
    
    >> select m 'd
    == none
    

    通过查看selectR3 中的规范(使用 eg ? series),我们也很快发现它接受以下类型的值作为第一个参数:series!, port!, map!(!), object!, none!

  2. R2 并没有真正的map!类型。它被hash!用作 R2 的“R2/Forward”前向兼容层的一部分。(看看你to map! [a 1 a 2]在 R2 和 R3 中得到了什么结果,看看这对你有什么影响。)

  3. 请注意,select您无法真正区分没有任何关联值的键或与#[none]值关联的键。如果你真的需要这种区别,在 R3 中很容易做到,你可以用它words-of来检索 a 的键map!

    >> words-of map [a 1 b 2]
    == [a b]
    

    但是,这还没有向后移植到 R2。

    然而,可以考虑依赖于实现内部的一种更可移植的方法是将map!(R3) 或hash!(R2) 转换回 a block!,并extract用于仅获取密钥:

     >> m: to map! [a 1 b 2]
     >> extract to block! m 2
     == [a b]
    
于 2013-01-08T04:54:02.203 回答