Perl 通过引用将哈希传递给子例程,不使用\&引用;:my_子例程(%my_哈希)

Perl 通过引用将哈希传递给子例程,不使用\&引用;:my_子例程(%my_哈希),perl,Perl,如何通过引用将哈希传递给子例程,而不使用子例程调用表达式(如my\u子例程(%my\u hash))中的\字符 更多解释:(以防前面的单行问题描述不够) 通过引用将变量传递给子例程,而不使用子例程调用表达式中的\字符,如my\u子例程($my\u var),可以通过如下方式定义子例程来实现: sub my_subroutine { my $var_ref = \shift; ... } 我尝试过使用散列的相同方法,但无法正常工作: sub my_subroutine {

如何通过引用将哈希传递给子例程,而不使用子例程调用表达式(如
my\u子例程(%my\u hash)
)中的
\
字符


更多解释:(以防前面的单行问题描述不够)

通过引用将变量传递给子例程,而不使用子例程调用表达式中的
\
字符,如
my\u子例程($my\u var)
,可以通过如下方式定义子例程来实现:

sub my_subroutine {
    my $var_ref = \shift;
    ...
}
我尝试过使用散列的相同方法,但无法正常工作:

sub my_subroutine {
    my $hash_ref = \shift;
    ...
}
我认为这是因为perl将任何传入散列的键-值对分割成一个列表(一维数组),它是
@
,传入数组也是如此(但只对值而不是键)


我正在寻找一种解决方法,使
my\u子例程(%my\u hash)
通过引用传递hash,而无需每次调用子例程时都在我的子例程参数(hash)前面加反斜杠字符
\
。这将有助于使我的主代码看起来更整洁,并将不整洁的部分留给子程序内部。另外,如果我与一大群开发人员一起工作,可能会有人忘记添加引用字符。我需要在子例程内部设置(哈希值总是通过引用传递给我的子例程),而不是由调用我的子例程的其他开发人员进行设置。

类似这样的设置如何:

#!/usr/bin/perl
use warnings;
use strict;
use Data::Printer;

my %h1 = ( a => 10, b => 20);
mySub(%h1);

sub mySub {
    my ($h1) = {@_};
    p $h1;
}

像这样的怎么样:

#!/usr/bin/perl
use warnings;
use strict;
use Data::Printer;

my %h1 = ( a => 10, b => 20);
mySub(%h1);

sub mySub {
    my ($h1) = {@_};
    p $h1;
}
,但您可以在这里使用它们来实现您的目标

sub my_subroutine (\%) {
    my $hashref = shift;
    ...
}

my_subroutine(%hash);
对于原型,子例程的第一个参数被强制为哈希引用

请注意,在子例程中,哈希作为哈希引用接收。您还需要使用命名哈希调用子例程

my_subroutine( { "anonymous" => "hash", "not" => "OK" } );  # not OK with proto
,但您可以在这里使用它们来实现您的目标

sub my_subroutine (\%) {
    my $hashref = shift;
    ...
}

my_subroutine(%hash);
对于原型,子例程的第一个参数被强制为哈希引用

请注意,在子例程中,哈希作为哈希引用接收。您还需要使用命名哈希调用子例程

my_subroutine( { "anonymous" => "hash", "not" => "OK" } );  # not OK with proto

有点不对劲。它不支持编辑传入的哈希。请检查我的测试代码。@Omar这是因为
{@\u}
@
的内容复制到一个新的匿名哈希中。您将无法使用此方法修改原始散列。在这种情况下,您必须使用prototype(并确保在使用sub之前定义了它)。请检查对gistGist的回复是否显示sub mySub(\%)为sub mySub(%)。请现在检查一下,有点不对劲。它不支持编辑传入的哈希。请检查我的测试代码。@Omar这是因为
{@\u}
@
的内容复制到一个新的匿名哈希中。您将无法使用此方法修改原始散列。在这种情况下,您必须使用prototype(并确保在使用sub之前定义了它)。请检查对gistGist的回复是否显示sub mySub(\%)为sub mySub(%)。请现在检查。Re“我想那是因为…”,唯一可以传递给subs(并从subs返回)的是一些标量。执行
my\u子例程(%my\u hash)
时传递的标量由键的副本和散列的(实际非副本)值组成。(原型可能会影响传递的标量。)Re“通过引用将变量传递给子例程而不使用
\
字符…”,变量始终使用Perl(这就是为什么
my$var\u ref=\shift;
可以获得对它的引用)。在调用者端使用
\
传递引用(当然,这是通过引用传递的)。“这将有助于使我的主代码看起来更整洁”,这也会误导人们了解实际发生的事情。如果这是你唯一的目标,那就忘了它。Re“我想那是因为…”,唯一可以传递给sub(并从sub返回)的是一些标量。执行
my\u子例程(%my\u hash)
时传递的标量由键的副本和散列的(实际非副本)值组成。(原型可能会影响传递的标量。)Re“通过引用将变量传递给子例程而不使用
\
字符…”,变量始终使用Perl(这就是为什么
my$var\u ref=\shift;
可以获得对它的引用)。在调用者端使用
\
传递引用(当然,这是通过引用传递的)。“这将有助于使我的主代码看起来更整洁”,这也会误导人们了解实际发生的事情。如果这是你唯一的目标,那就忘了它。看看优秀的汤姆·克里斯蒂安森。我认为,向OP暗示使用原型子程序是可以的,这样他们就不必在调用参数中加反斜杠,这是适得其反的,OP大概是个初学者。我认为向OP暗示使用原型子程序是可以的,这样他们就不必在调用参数中加反斜杠,这会适得其反,OP可能是个初学者。