代码之家  ›  专栏  ›  技术社区  ›  Christopher Bottoms zerkms

为什么:{}创建一个“Hash[Mu,Any]”对象(它是什么,与普通的“Hash”相比如何)?

  •  13
  • Christopher Bottoms zerkms  · 技术社区  · 7 年前

    起初,我只是想知道为什么在这段代码的第2行中的空大括号之前有一个冒号(来自 Perl 6 Advent Calendar, December 25, 2018

    sub is-happy( $n is copy ) {
        my $seen-numbers = :{};
        while $n > 1 {
            return False if $n ∈ $seen-numbers;
            $seen-numbers{$n} = True;
            $n = $n.comb.map(*²).sum
        }
        return True;
    }
    
    say is-happy(7);     # True
    say is-happy(2018);  # False
    

    这段代码几乎可以立即运行。我试过了 say $seen-numbers.^name; 发现是 Hash[Mu,Any]

    然而,当我移除结肠时, is-happy(7) 返回 True is-happy(2018) 说出$SEED数字。^name; Hash .

    所以很明显,, :{} 结果创建了一个 散列[亩,任何] . 这是怎么回事?这是一种变通方法还是习惯用法?什么是 散列[亩,任何] 它和正常的相比又如何呢 搞砸 ?

    1 回复  |  直到 6 年前
        1
  •  14
  •   Elizabeth Mattijsen    7 年前

    A. Hash Str 钥匙。任何不是钥匙的钥匙 Str 在将值存储在该字符串键下之前,将强制转换为1。这个 {} 构造一个空的 .

    这种行为可以通过给予改变 搞砸 类型参数。A. Hash[Int] 例如,仍然具有自动强制字符串键,但只能存储 Int Array[Int] 只能储存 Int 价值观)。还可以传递第二个类型参数来选择键的类型。这将创建通常称为“对象哈希”的内容,并存储索引器中提供的确切密钥。那么 Hash[Mu,Any] 是具有无约束值和 Any 钥匙类型(几乎所有类型都属于 任何 ,但 Junction ).这个 .WHICH 密钥的值用于散列。

    大多数情况下,不会使用 Hash[TValue,TKey] has Array %!edges-from{Mu} . 还有一种方法可以创建匿名对象哈希, :{} ,这是您在示例中观察到的。

    $seen-numbers{$n} = True;
    

    这个 $n 将存储为 它的 相反,我们会有 Str

    return False if $n ∈ $seen-numbers;
    

    ,存储 s、 然后 可能与散列中的一个键相同;如果是,则算法终止。但是,对于普通哈希,使用 {} ,钥匙是 Str ,因此与 Int

    该计划符合其自身的决定。可以这样写:

    return False if $seen-numbers{$n}:exists;
    

    然后它将与 ( 搞砸 Str 对于每次存储和查找,使用 :{} :{} ,从而使 ∈ ,可以认为更具可读性(特别是如果目标受众是习惯于阅读此类数学运算符的人)。

    编写程序的另一种可能更清晰的方法是:

    my %seen-numbers is SetHash;
    while $n > 1 {
        return False if $n ∈ %seen-numbers;
        %seen-numbers{$n} = True;
        $n = $n.comb.map(*²).sum
    }
    return True;
    

    这更清楚地表明我们正在考虑 %seen-numbers 作为一个集合,尽管在本例中,名称对其用途几乎没有疑问。

    推荐文章