回答
return;
将返回列表上下文中的空列表,但在标量上下文中返回undef
。即使在列表上下文中,return undef;
也会始终返回单个值undef
。
在一般情况下,它通常不是从子程序一个好主意,return undef;
通常在列表环境中使用:
sub foo { return undef }
if (my @x = foo()) {
print "oops, we think we got a result";
}
在一般情况下,它通常不是从子程序一个好主意,return;
通常在标量上下文中使用,因为它会不会像用户希望在列表环境:
sub foo { return }
%x = ('foo' => foo(), 'bar' => 'baz');
if (! exists $x{'bar'}) {
print "oops, bar became a value, not a key";
}
这两种错误的发生相当多的实践中,后者更是这样,也许是因为预期会返回一个标潜艇更共同。如果预计会返回一个标量,那么最好返回一个标量。
鉴于
sub foo { return; }
sub bar { return undef; }
在标量情况下,他们的行为相同。
my $foo = foo(); # $foo is undef
my $bar = bar(); # $bar is undef
在列表环境里,他们的行为不同
my @foo = foo(); # @foo is() (an empty list)
my @bar = bar(); # @bar is (undef) (a one-element list)
注意,一个元素的列表是在布尔上下文中的真实价值,即使唯一的元素是undef
。
一般来说,从子程序中通常不是一个好主意return undef;
,因为它在上下文中的表现如何。
我想我仍然同意PBP。
1)你应该避免嵌套函数调用:
my $result = bar();
foo(1, $result, 2);
2)你应该始终是明确的(做 “复杂” 的事情)时:
foo(1, scalar bar(), 2);
1)它不仅仅是嵌套函数调用。 2)是的,从呼叫者的角度来看,这将是一件好事。从被调查者的角度来看,它不应该被指望。 – ysth 2010-08-11 01:37:02
1)更多的例子呢? 无论如何,我相信你会最终以不稳定的结果更经常 $ perl -wle'sub get_values {return undef; };我的@values = get_values;打印标量@values;' 如果你想更加明确和正确,总有Contextual :: Return http://p3rl.org/Contextual::Return – nicomen 2010-08-11 12:23:09
你的'get_values'旨在用在列表上下文中,因此应该_不''返回undef'。但是如果你有一个返回标量的'get_value'函数,它应该_always_返回一个标量,而不是一个空列表,所以它会使用'return undef'。查看ysth的答案。 – cjm 2010-09-16 21:39:30
书 “Perl的最佳实践”建议使用return;
而不是return undef;
,因为后者会在列表上下文中返回一个元素列表(其他答案已经提到了这一点)。根据这本书,这将是一个“讨厌的错误”。但是,我认为任何返回都不会导致严重的错误(可能很难找到),而在列表上下文中调用布尔函数似乎相当容易调试。
所以我总是回东西(计算结果为)假我布尔函数(通常为0假,1为真)。 (是的,这也将返回列表上下文中的一个元素列表 - 因此该书中的评论在技术上是正确的 - 但是然后实际的错误将在列表上下文中调用布尔函数)。
To要清楚,我仍然推荐这本书。它提供了很多好的建议。
我在Damian Conway(O'Reilly Media,Inc.)出版的书“Perl Best Practices”中提到了第9章(子例程),第199/200页(“使用纯粹的返回来返回失败”)。 ISBN 978-0-596-00173-5。不确定是否有另一个/更新的版本。
附注:
当否定某些东西时,Perl似乎会返回一个空字符串。 my $foo = 5; return !$foo;
返回q()。
'!$ foo'是空字符串,因为Perl使用1表示true,空字符串表示false。由于'!',你在布尔上下文中。 – 2015-01-15 22:34:20
不,'!5是规范的假值,在字符串上下文中是“”,在数字上下文中是0。 – ysth 2015-09-13 20:57:15
- 1. “退货姓名”有什么区别?和“返回this.name”
- 2. e.preventDefault();有什么区别?并返回false?
- 3. 为什么event.ctrlKey返回undef?
- 4. return;返回true并返回false - 有什么区别?
- 5. “perl -n”和“perl -p”有什么区别?
- 6. 返回与否有什么区别?
- 7. 在Spring MVC中返回ModelAndView和返回String有什么区别?
- 8. 在Strawberry Perl中,perl \ lib和perl \ site \ lib有什么区别?
- 9. 返回View()和返回base.View()之间有什么区别?
- 10. Onkeydown返回false和返回super.onkeydown()之间有什么区别?
- 11. 在scrapy 1.3中,收益请求和退货请求之间有什么区别?
- 12. Perl中'for'和'foreach'有什么区别?
- 13. Perl中的'eq'和'=〜'有什么区别?
- 14. Perl中BAREWORD和* BAREWORD有什么区别?
- 15. Perl中$ dxyabc和$ {dxyabc}有什么区别?
- 16. “perl test.pl”和“./test.pl”有什么区别?
- 17. Perl中grep和map有什么区别?
- 18. Perl Spreadsheet :: ParseExcel无法解析并返回undef
- 19. 退出和退出有什么区别!在红宝石?
- 20. TouchID:回退(输入密码)和取消有什么区别?
- 21. SWIFT中的继续,休息,跌倒,投掷和退货有什么区别?
- 22. 在jQuery中返回promise()或延迟有什么区别?
- 23. R中打印和退货的区别?
- 24. 打印和退货之间的区别
- 25. 在递归函数中返回函数和不返回有什么区别?
- 26. 所有的fork函数返回值有什么区别?
- 27. 在Scala Akka期货中,map和flatMap有什么区别?
- 28. 延迟陈述与陈述在退货前的区别是什么?
- 29. jsch的ChannelSftp中退出和退出有什么区别?
- 30. 退出和退出配置单元之间有什么区别
在第二个例子中,我会说错误不是foo的定义,而是在胖逗号的右侧有一个sub。恕我直言,这是脆弱的编程风格。 – nslntmnx 2014-08-01 00:10:18
@nslntmnx:我不清楚胖逗号与它做什么或者你会做什么。你可以解释吗? – ysth 2014-08-01 00:38:04
这一切都源于这样一个事实,即胖逗号不*强制标量上下文在右侧。恕我直言,在第二个例子中,亚富的定义是完美的。失败的原因是在逗号右侧有一个子呼叫的可疑编码风格。在右边有一个子呼叫(如你所示)可能导致钥匙/对被损坏,因此编码风格很脆弱。 – nslntmnx 2014-08-01 05:12:33