为什么即使@array包含与LIST相同的元素,@array~~LIST仍返回false



我有

@a = (1,2,3); print (@a ~~ (1,2,3))

@a = (1,2,3); print (@a == (1,2,3))

第一个是我期望工作的,但它没有打印任何内容。第二个确实打印了1。

为什么?在@a ~~ (1,2,3)的情况下,智能匹配运算符~~不应该匹配吗?

接下来,让我们考虑一下略有不同的

@a ~~ (1,2,3)

~~在标量上下文中评估其自变量,因此以上内容与相同

scalar(@a) ~~ scalar(1,2,3)
  • @a(在任何上下文中)返回对@a的引用
  • 标量上下文中的1, 2, 3类似于do { 1; 2; 3 },返回3

因此,减去几个警告*,上述内容相当于

@a ~~ 3

你真正想要的是

@a ~~ do { my @temp = (1,2,3); @temp }

可以缩短为

@a ~~ [ 1,2,3 ]

最后,~~的魔力使@a可以写成@a,因此可以进一步缩短为

@a ~~ [ 1,2,3 ]

*—始终使用use strict; use warnings;

如果您在右侧使用数组或数组引用,而不是列表,Smart match会尝试执行我认为您期望的操作。

$ perl -E '@a = (1, 2, 3); say (@a ~~ (1, 2, 3))'
$ perl -E '@a = (1, 2, 3); say ((1, 2, 3) ~~ @a)' # also misguided, but different
1
$ perl -E '@a = (1, 2, 3); say (@a ~~ [1, 2, 3])'
1

从列表和数组之间的区别开始?在秘鲁。它特别向你展示了你对价值观的选择是错误的。

你也可以先写下为什么你希望每个人都能工作或不工作,这样我们就可以纠正你的期望。你为什么认为你会得到你期望的结果?

至于智能匹配位,ARRAY ~~ LIST没有规则。智能匹配仅适用于perlsyn中其表中枚举的对。这将迫使它成为其中一对。

当你遇到这些问题时,可以尝试更多的情况:

#!perl
use v5.10.1;
use strict;
use warnings;
my @a = (1,2,3);
say "@a is @a";
say "@a ~~ (1,2,3) is ", try( @a ~~ (1,2,3) );
say "@a ~~ [1,2,3] is ", try( @a ~~ [1,2,3] );
say "@a ~~ 3 is ", try( @a ~~ 3 );
say "3 ~~ @a is ", try( 3 ~~ @a );
say '';
my @b = (4,5,6);
say "@b is @b";
say "@b ~~ (4,5,6) is ", try( @b ~~ (4,5,6) );
say "@b ~~ [4,5,6] is ", try( @b ~~ [4,5,6] );
say "@b ~~ 3 is ", try( @b ~~ 3 );
say "3 ~~ @b is ", try( 3 ~~ @b );
say '';
say "@b ~~ @a is ", try( @b ~~ @a );
sub try { $_[0] || 0 }

各种案例的输出是你误读文档的线索:

Useless use of a constant (2) in void context at test.pl line 8.
Useless use of a constant (4) in void context at test.pl line 17.
Useless use of a constant (5) in void context at test.pl line 17.
@a is 1 2 3
@a ~~ (1,2,3) is 0
@a ~~ [1,2,3] is 1
@a ~~ 3 is 0
3 ~~ @a is 1
@b is 4 5 6
@b ~~ (4,5,6) is 0
@b ~~ [4,5,6] is 1
@b ~~ 3 is 0
3 ~~ @b is 0
@b ~~ @a is 0

最新更新