围绕变量的卷曲括号

and*_*son 15 syntax perl

我有这段代码,我正试图解决这个问题,我甚至不知道它的语法是否正确(我想这是练习的一部分!)

%{$records}
Run Code Online (Sandbox Code Playgroud)

花括号表示什么?我见过相同的情况,但是使用了@运算符而不是$if,这会产生影响.

多谢你们!

Gre*_*con 13

perlref文档"使用参考"部分解释.

2.在您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何地方,您可以使用BLOCK替换标识符,返回正确类型的引用.换句话说,前面的例子可以这样写:

   $bar = ${$scalarref};
   push(@{$arrayref}, $filename);
   ${$arrayref}[0] = "January";
   ${$hashref}{"KEY"} = "VALUE";
   &{$coderef}(1,2,3);
   $globref->print("output\n"); # iff IO::Handle is loaded
Run Code Online (Sandbox Code Playgroud)

在您的情况下,$records必须是对哈希的引用(因为最外层%),{$records}是一个返回引用的块,并%{$records}给出原始哈希.

花括号围绕着一个真正的块.实际上,您可以用上面的代码替换

%{ if ($records) { $records } else { $default_records } }
Run Code Online (Sandbox Code Playgroud)

但是,正如文档前面所指出的,即使是问题中较短的版本也可以简化.

1.在标识符(或标识符链)作为变量或子例程名称的一部分的任何地方,您可以使用包含正确类型引用的简单标量变量替换标识符:

   $bar = $$scalarref;
   push(@$arrayref, $filename);
   $$arrayref[0] = "January";
   $$hashref{"KEY"} = "VALUE";
   &$coderef(1,2,3);
   print $globref "output\n";
Run Code Online (Sandbox Code Playgroud)

因为$records是一个简单的标量,%$records是底层哈希.

如果$records是对数组的引用,则取消引用它的语法将是@$records@{$records}.


Bor*_*din 8

与许多Unix shell一样,Perl允许使用大括号来分隔变量标识符,因此my ${scalar}也是如此my $scalar.这很有用,例如,当将变量的值插入字符串时,何时"$scalartext"查找带有标识符的变量scalartext,何时是预期的$scalar.'text'.而不是这样你可以写,"${scalar}text"以获得正确的结果.

Perl将接受一个变量标识符或一个返回对大括号内变量的引用的表达式,因此%{$hashref}它是相同的%$hashref.请注意,字符串是不可接受的,因为它被视为符号引用,这是一个错误strict 'refs',因此${'scalar'}这里是错误的.

在你的情况下,%{$records}是相同的%$records,有些人更喜欢它,因为它使解除引用清晰.它表示哈希引用所引用的哈希值$records.

  • 它恰好是一个分隔符.这是一个故意但偶然的财产.基本属性是大括号建立一个块.方便,并且设计的一部分,BLOCK的值可以被周围的表达式使用,而不会模糊BLOCK开始或结束的位置. (2认同)

Que*_*tin 5

这是你取消引用参考的方式.

perldoc perlref.

像往常一样,%或者@说明你想要什么类型的数据("哈希"或"数组").

接下来是一个 {},它返回对相应数据类型的引用.

所以:%{$records}采用$records包含对哈希的引用的标量(),并返回一个哈希值.

  • @Borodin - 来自链接文档:您将标识符(或标识符链)作为变量或子例程名称的一部分放置的任何位置,您可以使用BLOCK替换标识符,返回正确类型的引用 (4认同)
  • @Borodin:不是一块?想想这个用严格; sub foo {\ @ {shift()}}; 打印"一年有@ {my $ v = sqrt(144); foo([$ v])}个月";` (2认同)