gpt4 book ai didi

hash - 这是Perl 6哈希还是 block ?

转载 作者:行者123 更新时间:2023-12-01 05:48:48 26 4
gpt4 key购买 nike

这是一些意外的行为,很可能会影响初学者。首先,这是故意的吗?其次,Perl 6还使用什么其他东西来猜测要创建哪个对象?它是从一开始就以为是Block还是Hash并在以后进行更改,还是最终决定?

您可以使用大括号和粗箭头构造Hash

my $color-name-to-rgb = {
'red' => 'FF0000',
};

put $color-name-to-rgb.^name; # Hash


使用其他对符号也会创建 Hash

my $color-name-to-rgb = {
:red('FF0000'),
};


但是,如果没有粗箭头,则会显示 Block

my $color-name-to-rgb = {
'red', 'FF0000',
};

put $color-name-to-rgb.^name; # Block


Hash文档仅提及在括号内使用 $_会创建 Block

还有其他定义哈希的方法,但是我要问的是语法的这一特定部分,而不是寻找我已经知道的解决方法。

$ perl6 -v
This is Rakudo version 2017.04.3 built on MoarVM version 2017.04-53-g66c6dda
implementing Perl 6.c.

最佳答案

这仅适用于任期position1

仅位于术语位置的括号代码({...})受此DWIM.2约束

在这些示例中,{...}不在术语位置:

if True { ... }   # always a block
class foo { ... } # always a package
put bar{ ... } # always a hash index


对于此答案的其余部分, {...}仅表示术语位置的括号代码。

摘要

如果 {...}具有显式或隐式签名,或包含顶层语句(包括变量声明),则始终为 Block

否则,这些是 Hash的唯一支撑块形式:


{}
{...}其中, ...是一个列表,其第一个元素是文字对(例如, :bar)或 %标记变量(例如, %foo)。


强制 BlockHash解释


要强制 {...}构造 Block而不是 Hash,请在开头即 ;处写一个 { ; ... }
要写空的 Block,请写 {;}
要强制 {...}构造 Hash而不是 Block,请改写 %(...),或遵循以下解释的规则。
要写入空的 Hash,请写入 {}


显式签名表示它是 Block

某些括号代码具有显式签名,即,其具有显式参数,例如下面的 $foo。无论括号内是什么,它总是构造一个 Block

say WHAT         { key => $foo, 'a', 'b' } # (Hash)
say WHAT -> $foo { key => $foo, 'a', 'b' } # (Block)


隐式签名也表示它是 Block

一些支撑代码具有隐式签名:


{...}中明确使用“代词”表示它是带有签名的 Block,如果还没有显式签名,则为隐式签名。代词是 $_@_%_
在没有显式调用者的情况下通过方法调用在 $_内隐式使用 {...}表示,如果该 Block还没有显式签名,则它是具有隐式签名的 { .foo }。换句话说,由于 (;; $_? is raw),即使 .foo也具有签名( $^foo)。
{...}中使用显式的“占位符”变量(例如 Block)还表示它是带有隐式签名(其中带有 $foo参数)的 Block


与显式签名一样,如果括号代码具有隐式签名,则无论括号内有什么内容,它始终会构造一个 Block

say WHAT { key => $_ }                     # (Block)
say WHAT { key => 'value', .foo, .bar } # (Block)


多个顶级语句表示它是一个 Block

say WHAT { :foo; (do 'a'), (do 'b') }     # (Block)
say WHAT { :foo, (do 'a'), (do 'b') } # (Hash)


第二行包含多个语句,但是它们在作为单个顶级表达式的列表的各个元素内产生值。

标识符的顶级声明表示它是 Block

声明是一个声明,但是我已经包括了本节,以防万一有人没有意识到这一点。

say WHAT { :foo, $baz, {my $bar} }        # (Hash)
say WHAT { :foo, $baz, (my $bar) } # (Block)


第一行包含一个 my $bar作为包含声明( {my $bar})的键。但是该声明属于内部 Block {...},而不是外部 Block。因此,就外部 {...}而言,内部 Hash只是一个值,因此外部支撑代码仍被解释为 {...}

相反,第二行直接在外部 Block内声明变量。所以这是一个 Block

仍然是 Hash,不是 Hash

回想一下,要成为 %,支撑代码的内容必须是一个以 Block标记或文字对开头的列表。因此,这些都会产生 Hash

my $bar = key => 'value';
say WHAT { $bar, %baz } # (Block)
say WHAT { |%baz } # (Block)
say WHAT { %@quux } # (Block)
say WHAT { 'a', 'b', key => $foo } # (Block)
say WHAT { Pair.new: 'key', $foo } # (Block)


Block

支撑代码,它不会属于上述任何一种情况,导致其成为 %,并且只是零个或多个以 Hash信号变量或文字对开头的值的列表,构造一个

say WHAT {                  }             # (Hash)
say WHAT { %foo } # (Hash)
say WHAT { %foo, ... } # (Hash)
say WHAT { foo => 42, ... } # (Hash)
say WHAT { :foo, ... } # (Hash)
say WHAT { key => $foo, ... } # (Hash)


脚注

1请参阅以下关于术语位置的答案的评论。

2 DWIM设计很麻烦。好的DWIM设计值得。但是每个DWIM都带有相应的WATs3。好的DWIM设计的关键是确保WAT的 barks are worse than their bites 4;树皮有用5;而且DWIM被认为值得一试。6

3 WAT指的是当开发人员觉得有些疯狂时,开发人员的意外惊喜。众所周知,对于大多数适用于大多数人的DWIM,在大多数情况下,不可避免地会有一个或多个相关的WAT使某些人感到惊讶,有时甚至使某些人从DWIM中受益。

4与该DWIM相关的WAT的含义有所不同。它通常是一个树皮(错误消息),使问题很明显,但可能更加晦涩:

say { a => 42 }() ;  # No such method 'CALL-ME' for invocant of type 'Hash'   WAT? Oh.
say { a => $_ }<a> ; # Type Block does not support associative indexing. WAT? Oh.

say { a => $_, b => 42, c => 99 } .elems # 1 WAT?????


5“树皮”是文档中的错误消息或警告。这些通常可以改进。参见 Lock.protect({}) fails, but with surprising message

6社区成员对于是否值得进行DWIM设计(特别是任何给定的DWIM)存在意见分歧。 cf my perspective vs Sam对这个问题的回答。

关于hash - 这是Perl 6哈希还是 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57941391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com