2010-09-14 126 views
6

從一個函數忽略返回的值。例如:有點毛病在PHP

// somefile.php 
function doSomething() { 
    // do lots of code, whatever... 
    return $something; 
} 

// mainfile.php 
include "somefile.php" 
doSomething(); // ignored the return value, we don't need it here 

當PHP函數返回一個值,但我們不關心它,會發生什麼?這種行爲有什麼問題,或者即使我們永遠不會在函數範圍之外使用它,我們是否應該始終獲取變量? PHP如何通過返回一個不會在函數範圍之外使用的值來管理資源?

+0

如果你返回一些東西但不需要它,那麼你爲什麼要返回「某物」。 ?只是做一個回報; – RobertPitt 2010-09-14 13:59:17

+0

Thomas Clayson給出了一個這樣的函數「mysql_query」下面的完美例子。也許我應該更好地解釋自己......並不是永遠不需要返回值,這只是我可能需要它,或者可能不需要。我想給用戶選擇。 – 2010-09-14 14:32:20

回答

11

返回值被丟棄。這樣做沒有任何問題。即使沒有明確的return功能做回null含蓄:

function foo() {} 
var_dump(foo()); // NULL 
+0

只是爲了增加...想想'mysql_query()'。你可以自己運行'mysql_query()',或者你可以把它的返回值賦給一個變量。 :)不管你是否忽略它,所有的代碼仍然運行。 – 2010-09-14 13:49:48

+0

@Thomas Clayson:當然,如果你需要返回的值進行進一步處理,你需要以某種方式處理它。但是,如果沒有,則不需要存儲它。 – Gumbo 2010-09-14 13:52:09

+2

+1對於「即使沒有明確返回的函數也會隱含地返回null:」 – RobertPitt 2010-09-14 14:03:26

2

它的代碼味道,每次返回的是不會被使用的東西時間意味着你沒有,你的受衆的想法 - 你可能會丟失一些其他的概念。

此外,這些功能通常遭受Command Query separation

幾個例子

  • array_unshift(&$arr, $value, ...)預規劃傳遞值數組,並返回數組的新的大小,多久你想要的信息?如果你這樣做,你總是可以撥打count($array)這是專爲此目的而設計的。

  • sort(&$arr) sorts傳遞數組,如果成功則返回。是否有意義?當發生錯誤時你應該知道,異常應該被引發/錯誤觸發,你是否真的想一直測試成功?你呢?

  • print_r()是一個超級例子,它根據傳入的參數返回true(總是如此無用)或字符串。這絕對不是api的樣子。

一個可能的例外可能是流暢的界面,如jQuery但就是非常具體案例。

提示:寫幾個測試並重新考慮你的架構,如果它確實沒有任何其他意義,它可能已經足夠了。但在這種情況下你應該小心。

+0

-1:那些* some *調用函數需要返回值而另一些不需要?你的一些例子實際上可能是糟糕的API設計的例子,但通常情況下,一些調用者需要返回值而不是其他的。 – Gravity 2011-10-03 03:48:32

+0

這正是我所說的 - 當「某些」呼叫不需要這個值時,你在API設計中失敗了。根本不應該返回,或者僅在因爲返回值而調用函數時才返回。 CQS就是這樣。 – 2011-10-03 07:37:45

+0

我剛剛重讀了你的答案 - CQS不是一個選項,它是必須的 - 混合查詢和命令一起導致難以維護的代碼。 CQS應該與避免靜態/全局是相同的工具箱。 – 2011-10-03 07:44:57

2

它沒有問題。如果你有一個函數返回一個值,但也會以某種方式改變程序的狀態(稱爲副作用),調用函數但忽略返回值只會導致所有的副作用被應用。當然,如果你沒有存儲它,你將無法使用返回值,但有時你想要的僅僅是調用的副作用。

有一些人相信設計API的方式,使得被稱爲副作用(命令)和函數的函數被調用來儘可能地分離程序(查詢)的某些狀態。這個原則被稱爲Command-Query Separation。這個想法是,所有返回事物的函數都不應該修改程序的狀態,因爲它們正在觀察它,觀察行爲不應該影響觀察到的狀態。所有不返回任何東西的函數都被視爲命令,專門用於其副作用。

因此,遵循這些原則的人可能會認爲,由於你的函數明顯應用副作用(或者你爲什麼要調用它而不關心返回值?),它不應該觀察任何狀態(有返回值) 。但是,請注意,這個原則並不總是要遵循這封信,並且也沒有達成一致。

爲什麼有些人提倡命令查詢分離?因爲如果在查詢之間沒有應用命令,它可以確保連續查詢返回相同的答案。這是一種不可變性的弱化形式,並且具有不變性可用於推理程序邏輯的優點的弱化形式。一致地應用時,對象在命令之間是不可變的。

在我看來,記住這個原則通常會導致API更少且程序邏輯更清晰,但不應過多。有時您可能需要應用副作用並返回一個值。但是,當返回值只是成功值時,請考慮在失敗時引發異常。

1

返回只是一種將函數內部的變量傳遞給函數以外的方法。除非函數被設置爲靜態,否則函數中的變量將被銷燬。爲了保留這個值,你可以分配一個變量來存儲它。

代碼中不需要返回變量是很常見的。事實上,不需要返回變量並不意味着沒有用於返回變量。

即使允許返回的函數或方法死掉也沒有不良影響,但這通常是不好的做法。當開發者創建回報時,它有一個原因。這個原因可能是一些事情,例如:函數的效果除了返回外可能沒有結果(這個例子不太可能落入你的情況),返回的結果可能是順序操作的參考,返回的結果可能用於調試。

我建議你找到返回結果的意圖並相應地處理它。通常,忽略返回結果可能會在您的應用程序中引入可預防的不可預測狀態。

例如,array_walk()。它通過引用處理你的數組,假設一切順利,沒有必要爲標準執行存儲返回變量;然而,如果它失敗了,你無法知道,如果你自動認爲它沒有失敗,你的應用程序可能會失敗或給出意想不到的結果。如果您已經收集了該返回變量並且發現它是錯誤的,那麼您可能會引發異常,試圖找出原因並再次嘗試,或記錄該異常以備將來參考。

7

對我來說,所有的碗到一個簡單的模式:

「的函數應該做的一兩件事。它應該做得很好。它只應該這樣做。「

如果您有多個原因調用該函數的功能很多。


語言的角度來看也絕對有無視的返回值沒有問題。從清潔代碼的立場有。

一個insert()函數應該在數據庫中插入一條記錄。不返回插入記錄的ID。你沒有要求那個。

一個setLatitude()應該修改的對象內部狀態不加載你的時區類和人物在時區緯度是和他們寫的數據庫。 (保存對象可以做到這一點)。


如果你有兩個理由來稱呼它提供一個以上的目的,但從因此它乾淨的代碼點的函數:「是否太多」

當然可以有案件結構在那裏它可以是有道理的,但作爲一般的經驗法則,忽視返回值可能是一種代碼味道。