Pair Constructor
— 焉知非鱼Pair Constructor
又是一个来自 Damian 的好东西,真的是你所期待的对话者和解释者的好东西。
胖逗号运算符,=>
,最初是用来分隔值的–但有一个变化。它的行为就像 ,
运算符一样,但修改了解析,将左操作数字符串化。
它为你节省了一些字符串的引号,所以这个哈希初始化的代码。
my %h = (
'a', 1,
'b', 2,
);
可以被写为:
my %h = (
a => 1,
b => 2,
);
在这里,裸a和b的解析是正确的,不需要把它们引用成字符串。不过,通常的哈希赋值语义还是一样的:一对对的值会被逐一处理,鉴于 =>
只是一个 “左侧字符串化"的逗号运算符,有趣的是,上面的代码就相当于这一块:
my %h = ( a => 1 => b => 2 => );
该提案建议改变这个"特殊"操作符的含义,使其成为一个新数据类型的构造函数, Pair:
一个 Pair 是由一个键和一个值构成的:
my @pairs = a => 42, 1 => 2;
say @pairs[0]; # a => 42
say @pairs[1]; # 1 => 2;
say @pairs[1].key.^name; # Int, not a Str
这里的 @pairs
列表只包含2个值,而不是4个,一个是方便我们串联的,第二个只是用裸的Int字面作为键。
事实证明,引入 Pair
不仅是一个方便操作的数据类型,这个变化还为…子程序提供了新的机会。
Raku 对签名的支持是一流的,这里既是为了 “第一旅行舱"的双关语,也是为了它的事情,是的,居然有 Signature、Parameter 和 Capture 作为一流的对象,这就可以有令人惊讶的解决方案。它支持命名参数,有大量的语法为它服务,这并不奇怪。而 Pair 类已经很自然地融入其中。
如果把 Pair 传给一个带有命名参数的子程序,其中键匹配,它就能正常工作,否则你就有一个 “完整"的 Pair,如果你想坚持,这里的一点语法可以帮助你。
sub foo($pos, :$named) {
say "$pos.gist(), $named.gist()";
}
foo(42); # 42, (Any)
try foo(named => 42); # Oops, no positionals were passed!
foo((named => 42)); # named => 42, (Any)
foo((named => 42), named => 42); # named => 42, 42
正如我们所看到的,设计一门语言是很有趣的:在一个部分所做的改变可能会对其他部分产生影响,而这些影响可能看起来很不相关,你最好希望你的选择在连接在一起的时候会有很好的效果。感谢 Damian 和所有参与 Raku 设计的人,感谢他们为之付出的巨大努力。
最后,但不是最不重要的:我们看到的 =>
火车发生了什么?好了,现在它做什么你的意思,如果你的意思是它做什么。
my %a = a => 1 => b => 2;
say %a.raku; # {:a(1 => :b(2))}
是的,这是一个键a指向值对的1指向值对的b指向值对的2,所以至少这次的方向是不错的。祝大家好运,保持方向!