【问题标题】:How can you assign values to a Hash key without concomitant boxing (i.e. itemization)?如何在没有伴随装箱(即逐项)的情况下将值分配给哈希键?
【发布时间】:2020-12-27 09:49:07
【问题描述】:

来自this SO question,我试图将List(或一般的非标量事物)作为分配给哈希键的值,这样:

my %syns-by-name does Associative[Str,List] = Bq => ("Bq", "becquerel", "becquerels");
my Str  @syns = %syns-by-name<Bq>;

但是,这不起作用。列表在分配之前会逐项列出,因此值始终是标量。您需要采取一种变通方法才能真正完成这项工作:

my %syns-by-name does Associative[Str,List] = Bq => ("Bq", "becquerel", "becquerels");

my @list := <C coulomb coulombs>;
%syns-by-name<C> := @list;

my Str  @syns = %syns-by-name<C>;
say @syns;

这将返回我们正在寻找的内容,一个列表。但是,我们如何才能直接在作业上执行此操作并说服列表是列表而不是逐项列表?

【问题讨论】:

  • 嗨@jjmerelo my Str @syns2 = @(%syns-by-name&lt;Bq&gt;); 给你你想要的吗?
  • @jubilatious1 可能,但我更多的是寻找定义变量的方法,而不是访问它的值。

标签: syntax raku


【解决方案1】:

假设您之后不需要突变,请使用 Map 而不是 Hash

my %syns-by-name is Map = Bq => ("Bq", "becquerel", "becquerels");
my Str @syns = %syns-by-name<Bq>;
say @syns; # [Bq becquerel becquerels]

由于不期望 Map 中的条目是可分配的,因此它不会为值创建 Scalar 容器。

【讨论】:

    【解决方案2】:

    怎么样:

    role deconting {
        method AT-KEY(\key) {
            callsame<>
        }
    }
    my %h does deconting = a => <a b c>;
    dd $_ for %h<a>;  # "a"␤"b"␤"c"␤
    

    这可以确保执行“去容器化”角色的哈希将始终返回去容器化的哈希中的任何内容。

    也可以在分配时使其去容器化,但要复​​杂得多,因为这需要调整至少两种方法:STOREASSIGN-KEY

    【讨论】:

      【解决方案3】:

      尽管@Jonathan_Worthington 和@Elizabeth_Mattijsen 给出了出色的答案,我还是想发布下面的代码,它利用了简单的去容器化:

      ~$ raku
      Welcome to ??????™ v2020.10.
      Implementing the ????™ programming language v6.d.
      Built on MoarVM version 2020.10.
      
      To exit type 'exit' or '^D'
      > my %syns-by-name =  Bq => ("Bq", "becquerel", "becquerels");
      {Bq => (Bq becquerel becquerels)}
      > my Str  @syns = %syns-by-name<Bq>;
      Type check failed in assignment to @syns; expected Str but got List (("Bq", "becquerel", ...)
        in block <unit> at <unknown file> line 1
      
      > my Str  @syns = %syns-by-name<Bq>[];
      [Bq becquerel becquerels]
      >
      

      我认为这里有一个学术问题,即变量如何定义与变量的值如何访问。但是,我不希望随便的读者得出结论,Raku 缺乏针对哈希和列表的功能。

      > my %syns-by-name  = Bq => ("Bq", "becquerel", "becquerels");
      {Bq => (Bq becquerel becquerels)}
      > dd $_ for %syns-by-name<Bq>[]
      "Bq"
      "becquerel"
      "becquerels"
      Nil
      > my $list = <C coulomb coulombs>;
      (C coulomb coulombs)
      > say $list.WHAT
      (List)
      > %syns-by-name<C> = $list
      (C coulomb coulombs)
      > dd $_ for %syns-by-name<C>[]
      "C"
      "coulomb"
      "coulombs"
      Nil
      >
      

      我希望这个答案不是多余的,普通读者会从中受益。谢谢。

      【讨论】:

        猜你喜欢
        • 2012-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-20
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多