回答
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