2012-05-01 15 views
6

Come potrebbe essere chiaro dal titolo quale approccio preferiremmo?Passare un parametro o restituirlo dalla funzione

L'intenzione è passare alcuni parametri di metodo e ottenere qualcosa come output. Possiamo passare un altro parametro e il metodo lo aggiornerà e il metodo non deve restituire nulla ora, il metodo aggiornerà solo la variabile di output e verrà riflesso al chiamante.

Sto solo cercando di inquadrare la domanda attraverso questo esempio.

List<String> result = new ArrayList<String>(); 

for (int i = 0; i < SOME_NUMBER_N; i++) { 
    fun(SOME_COLLECTION.get(i), result); 
} 

// in some other class 
public void fun(String s, List<String> result) { 
    // populates result 
} 

contro

List<String> result = new ArrayList<String>(); 

for (int i = 0; i < SOME_NUMBER_N; i++) { 
    List<String> subResult = fun(SOME_COLLECTION.get(i)); 
    // merges subResult into result 
    mergeLists(result, subResult); 
} 

// in some other class 
public List<String> fun(String s) { 
    List<String> res = new ArrayList<String>(); 
    // some processing to populate res 
    return res; 
} 

Capisco che si passa il riferimento e un altro non lo fa.

Quale preferiamo (in diverse situazioni) e perché?

Aggiornamento: considerarlo solo per oggetti mutabili.

+0

Non sono sicuro di cosa stai chiedendo. Stai chiedendo in quali situazioni dovresti passare una variabile ad un metodo o acquisirlo nel metodo con un getArg() o qualsiasi altra cosa possa essere chiamata? – Charles

+0

No, lo stai fraintendendo o non potrei trasmettere. Mi chiedo: dovremmo passare una variabile a una funzione come riferimento o restituirla dalla funzione? In quali situazioni dovremmo usare uno di questi? Spero, sono chiaro! – instanceOfObject

risposta

14

Il ripristino di un valore dalla funzione è generalmente un modo più semplice di scrivere codice.Passare un valore e modificarlo è più stile C/C++ a causa della natura di creare e distruggere i puntatori.

Gli sviluppatori in genere non si aspettano che i loro valori vengano modificati passando attraverso una funzione, a meno che la funzione non specifichi esplicitamente di modificare il valore (e spesso si scremano la documentazione).

Tuttavia, ci sono delle eccezioni.

Considerare l'esempio di Collections.sort, che in realtà esegue una sorta di elenco di un posto. Immagina un elenco di 1 milione di articoli e lo stai smistando. Forse non vuoi creare una seconda lista che abbia altre 1 milione di voci (anche se queste voci puntano all'originale).

È anche una buona pratica favorire l'uso di oggetti immutabili. Gli oggetti immutabili causano molti meno problemi nella maggior parte degli aspetti dello sviluppo (come il threading). Quindi, restituendo un nuovo oggetto, non si costringe il parametro a essere mutabile.

La parte importante è essere chiari sulle vostre intenzioni nei metodi. La mia raccomandazione è di evitare di modificare il parametro quando possibile poiché non è il comportamento più tipico in Java.

+0

Ha senso! Grazie! – instanceOfObject

0

Restituirlo manterrà il codice più pulito e causerà meno accoppiamento tra metodi/classi.

0

Questo è più su best practice e il proprio metodo per programmare. Direi che se sai che questo sta per essere un valore della funzione tipo di ritorno come:

funzione IsThisNumberAPrimeNumber {}

poi si sa che questo è solo andare a ritornare sempre un valore booleano. Di solito uso le funzioni come programmi di supporto e non come procedure secondarie di grandi dimensioni. Applico anche le convenzioni di denominazione che aiutano a dettare cosa mi aspetto che la funzione \ sub restituisca. Esempi:

GetUserDetailsRecords GetUsersEmailAddress IsEmailRegistered

Se si guarda a quei 3 nomi, si può dire il primo sta per darvi qualche lista o classe di più record di dettaglio dell'utente, la seconda vi darà un valore di stringa di una e-mail e il terzo probabilmente ti darà un valore booleano. Se cambi il nome, cambi il significato, quindi direi di tenerlo in considerazione.

0

La ragione per cui non penso che capiamo è che si tratta di due tipi di azioni completamente diversi. Passare una variabile a una funzione è un mezzo per fornire dati di una funzione. Restituirlo dalla funzione è un modo per trasferire i dati da una funzione.

Se vuoi dire la differenza tra queste due azioni:

public void doStuff(int change) { 
    change = change * 2; 
} 

e

public void doStuff() { 
    int change = changeStorage.acquireChange(); 
    change = change * 2; 
} 

Poi il secondo è generalmente pulito, ma ci sono diverse ragioni (sicurezza, funzione di visibilità, ecc) che può impedirti di passare i dati in questo modo.

È anche preferibile perché rende più facile riutilizzare il codice, oltre a renderlo più modulare.

6

Si dovrebbe restituirlo. Il secondo esempio che hai fornito è la strada da percorrere.

Prima di tutto, è più chiaro. Quando altre persone leggono il tuo codice, non c'è traccia che potrebbero non notare che il parametro viene modificato come output. Puoi provare a nominare le variabili, ma quando si tratta di leggibilità del codice, è preferibile.

Il GRANDE motivo perché si dovrebbe restituirlo piuttosto che passarlo, è con oggetti immutabili. Il tuo esempio, la lista, è mutabile, quindi funziona bene. Ma se si dovesse provare a utilizzare una stringa in questo modo, non funzionerebbe.

come stringhe sono immutabili, se si passa una stringa come parametro, e quindi la funzione dicesse:

public void fun(String result){ 
    result = "new string"; 
} 

Il valore del risultato che avete passato in non sarebbe essere modificato. Invece, la variabile di ambito locale 'result' ora punta a una nuova stringa all'interno di fun, ma il risultato nel metodo di chiamata punta ancora alla stringa originale.

Se si chiama:

String test = "test"; 
fun(test); 
System.out.println(test); 

Si stamperà: "test", non "nuova stringa"!

Quindi, sicuramente, è meglio tornare. :)

+0

Sì! Che capisco, la domanda era solo per oggetti mutabili! Grazie per la risposta btw! – instanceOfObject

+0

Nessun problema. Sì, per gli oggetti mutabili funziona, e in alcuni casi sarà preferibile (non puoi restituire più oggetti senza usare una tupla) ma generalmente se è tutto uguale, restituire è uno stile di codice migliore. – SpacePrez

Problemi correlati