如何在Perl 6中声明一个数字类型的哈希嵌套哈希?

8
默认情况下,哈希表将所有键转换为字符串。这会在键为接近的数字时引起问题:
> my %h; %h{1/3} = 1; %h{0.333333} = 2; dd %h;
Hash %h = {"0.333333" => 2}

当然,这个问题可以通过以下方式解决:
>  my %h{Real}; %h{1/3} = 1; %h{0.333333} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = 0.333333 => 2, <1/3> => 1)

但是现在我需要一个数字哈希的哈希,例如{ 1/3 => { 2/3 => 1, 0.666667 => 2 } }

> my %h{Real}; %h{1/3}{2/3} = 1; %h{1/3}{0.666667} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = <1/3> => ${"0.666667" => 2})

我该如何解决这个问题?

我能够找到的最佳解决方法是以下的绕过方式:

> my %h{Real}; %h{1/3} //= my %{Real}; %h{1/3}{2/3} = 1; %h{1/3}{0.666667} = 2; dd %h;
Hash[Any,Real] %h = (my Any %{Real} = <1/3> => $(my Any %{Real} = <2/3> => 1, 0.666667 => 2))

但这仅仅是令人烦恼的。
1个回答

13
以下内容是有效的:
my Hash[Real,Real] %h{Real};
%h{1/3} .= new;
%h{1/3}{2/3} = 1;

这并不是很好。


以下方法也可以作为解决方案。

my Hash[Real,Real] %h{Real};
%h does role {
  method AT-KEY (|) is raw {
    my \result = callsame;
    result .= new unless defined result;
    result
  }
}

%h{1/3}{2/3} = 1;

say %h{1/3}{2/3}; # 1
如果您有超过一个这样的变量:
role Auto-Instantiate {
  method AT-KEY (|) is raw {
    my \result = callsame;
    result .= new unless defined result;
    result
  }
}

my Hash[Real,Real] %h{Real} does Auto-Instantiate;

2
谢谢。my Hash[Real,Real] %h{Real}; 就是我一直在寻找的。不过手动实例化(或使用角色)有点遗憾。可以说,Rakudo 应该使用这种语法自动实例化。 - mscha
3
我会将 "Instead of result .= new unless defined result; I would have written this as result .= new without result;" 翻译为 "我会将 result .= new unless defined result; 改写成 result .= new without result;。" - Elizabeth Mattijsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接