我刚刚开始与一个新的团队新工作.他们告诉我,我们在perl模块中返回ref而不是value.我还看到了return +{foo=>'bar'}; and return {foo=>'bar'};
Whats的不同之处?是否返回ref或value?
ike*_*ami 21
该+
中return +{foo=>'bar'}
是完全无用的.
首先,一些背景.
Perl语言含糊不清.举个例子
sub f {
{ } # Is this a hash constructor or a block?
}
Run Code Online (Sandbox Code Playgroud)
{ }
是块的有效语法("裸循环").
{ }
是哈希构造函数的有效语法.
两者都被允许作为声明!
所以Perl必须猜测.Perl通常猜对了,但并不总是这样.你可以给它"提示".一元 - +
可以用来做到这一点.一元+
是一个完全透明的运营商; 它什么都不做.但是,必须后跟表达式(不是语句).{ }
只有一种可能的含义作为表达.
+{ } # Must be a hash constructor.
Run Code Online (Sandbox Code Playgroud)
同样,你可以欺骗Perl来猜测另一种方式.
{; } # Perl looks ahead, and sees that this must be a block.
Run Code Online (Sandbox Code Playgroud)
这是Perl猜错的一个例子:
map { {} } 1..5 # ok. Creates 5 hashes and returns references to them.
map {}, 1..5 # XXX Perl guesses you were using "map BLOCK LIST".
map +{}, 1..5 # ok. Perl parses this as "map EXPR, LIST".
Run Code Online (Sandbox Code Playgroud)
至于问题中的代码,return
必须跟一个表达式(如果有的话),所以只有一种可能的解释return { ... };
,所以在+
那里完全没用.
大多数人只在必要时才消除歧义.其他人可能会添加+
它的含糊不清(即使Perl猜对了).但这是我第一次听说+
在每个哈希构造函数前使用它.
Thi*_*Not 10
有什么不同?
那些是完全一样的,所以这+
是无关紧要的.你可以通过使用B :: Deparse来看到这个:
$ perl -MO=Deparse -e'sub foo { return { foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
$ perl -MO=Deparse -e'sub foo { return +{ foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,您都会返回对哈希的引用.
正如Hunter McMillen在评论中所说,在某些情况下,您需要使用一元运算+
符来解决歧义.
例如,要区分匿名哈希和块中的块map
:
$ perl -e'@a = map { $_ => "foo" }, 1..3' # { ... } treated as a block
syntax error at -e line 1, near "},"
Execution of -e aborted due to compilation errors.
$ perl -e'@a = map +{ $_ => "foo" }, 1..3' # { ... } treated as a hashref
Run Code Online (Sandbox Code Playgroud)
是否返回ref或value?
通过"返回一个值",我假设你的同事意味着这样的事情:
sub foo {
my %bar = ( baz => 'qux' );
return %bar; # as opposed to \%bar
}
my %hash = foo();
Run Code Online (Sandbox Code Playgroud)
子例程只能返回一个标量列表,所以这大致相当于
my %hash = ('baz', 'qux');
Run Code Online (Sandbox Code Playgroud)
如果%bar
包含许多项目,则复制此列表会变得昂贵,因此最好返回引用:
sub foo {
my %bar = ( baz => 'qux' );
return \%bar;
}
my $hashref = foo();
Run Code Online (Sandbox Code Playgroud)