2013-01-10 3 views
5

Sto solo imparando a programmare in scala. Ho una certa esperienza nella programmazione funzionale, come ho nella programmazione orientata agli oggetti. La mia domanda è abbastanza semplice, ma complicata:Scala immutable vs mutable. Qual è il modo in cui si dovrebbe andare?

Quali strutture dovrebbero essere utilizzate in Scala? Dovremmo limitarci a immutabili, ad es. modificando le liste eseguendone iterazioni e inserendone una nuova insieme, oppure optando per le mutabili? Qual è la tua opinione su questo, quali sono gli aspetti prestazionali, aspetti legati alla memoria, ...

Sono probabile che programmassi in uno stile funzionale, ma spesso si espande a un folle sforzo per fare cose che sono fatto facilmente utilizzando mutables. È dipendente dalla situazione, che cosa usare?

+2

Questa domanda è molto generale. Consiglio vivamente di identificare quei problemi che ritenete richiedano uno sforzo "folle" per risolvere funzionalmente e porre domande su di essi. Potresti apprendere nuove tecniche funzionali che rendono lo sforzo ragionevole - o persino più semplice rispetto all'utilizzo di dati mutabili! –

+9

Ci sono altre domande che affrontano questo problema, e questa domanda è troppo vaga o ampia per ammettere una buona risposta, ma in breve: fare ciò che funziona meglio _overall_. Come regola generale, utilizzare una soluzione immutabile se non ci sono gravi inconvenienti; dopo di ciò, preferisci uno mutabile in cui lo stato mutabile non sfugge al contesto locale (cioè il metodo che stai usando), seguito da uno in cui lo stato mutevole è almeno nascosto nella classe (quindi non c'è bisogno di preoccuparsene _except_ quando si utilizzano più thread - e documentare la mancanza di sicurezza del thread). Usa l'immutabilità perché ti aiuta, non quando fa male! –

+0

Nel rapporto facile/insano: la mutabilità è spesso più facile da programmare e eseguire il debug quando si ha a che fare con un singolo thread e diventa faticosamente difficile programmare e eseguire il debug quando si utilizzano più thread. –

risposta

3

(ho pensato che questo deve essere un duplicato, ma non potrebbe facilmente trovare un altro simile in precedenza, quindi mi permetto di rispondere ...)

Non c'è una risposta generale a questa domanda. La regola generale suggerita dai creatori di Scala è di iniziare con valori e strutture immutabili e attenersi a loro finché ha senso. Puoi quasi sempre creare una soluzione praticabile al tuo problema in questo modo. Ma se no, naturalmente, essere pragmatico e usare la mutabilità.

Una volta che hai una soluzione, puoi modificarla, verificarla, misurarne le prestazioni, ecc. Se trovi che, ad es. è troppo lento o eccessivamente complesso, identifica la parte critica di esso, capisce cosa lo rende problematico e - se necessario - reimplementalo usando variabili mutevoli, idealmente mantenendolo isolato dal resto del programma. Nota che, in molti casi, è possibile trovare una soluzione migliore anche all'interno del regno immutabile, quindi prova prima a cercare lì. Soprattutto per un principiante come me, succede ancora regolarmente che la soluzione migliore che ho potuto trovare sembrava contorta e complessa senza un apparente modo di migliorarla - fino a vedere una soluzione semplice ed elegante allo stesso problema in poche righe di codice, creato da uno sviluppatore esperto di Scala che controlla maggiormente la potenza del linguaggio e delle sue librerie.

+0

Ho pensato anch'io (che ci deve essere un argomento a riguardo) e mi sono guardato intorno ma non ho trovato nulla Ho pensato di chiederlo a riguardo. Ty per la tua risposta, signore! – smoes

3

solito obbedire le seguenti regole:

  • Non utilizzare mai Vars mutevoli statici

  • Tenere tutti i tipi di dati definiti dall'utente (tipicamente classi case) immutabili a meno che non sono molto costosi da copiare. Ciò semplificherà gran parte della logica dell'applicazione.

  • Se una struttura/raccolta dati è intrinsecamente mutabile (ovvero è progettata per cambiare nel tempo), l'utilizzo di una struttura/raccolta dati mutevole potrebbe essere appropriato. Un esempio potrebbe essere un vasto mondo di gioco che viene aggiornato quando i giocatori si muovono. Ricorda di (quasi) non condividere mai queste strutture dati tra i thread.

  • E 'bene usare mutabili Vars locali nei metodi

  • Utilizzare collezioni immutabili per i risultati di funzione. Questi possono essere valutati in modo rigoroso o pigramente a seconda di cosa offre le migliori prestazioni nel contesto utilizzato. Stai attento se usi un risultato valutato pigramente che dipende da una collezione mutevole.

3

Preferibilmente immutabile allo stato mutabile. Usa lo stato mutabile solo dove è assolutamente necessario.Alcuni motivi importanti includono:

  • Prestazioni. Le librerie standard fanno largo uso di vars e while loop, anche se questo non è un idiomatico di Scala. Tuttavia, ciò non dovrebbe essere emulato, ad eccezione dei casi in cui è stato impostato con profilo per determinare che la modifica del codice per essere più imperativa porterà un significativo aumento delle prestazioni.

  • I/O. L'I/O, o l'interazione con il mondo esterno è intrinsecamente dipendente dallo stato, e quindi deve essere trattato in maniera mutevole.

Questo non è diverso dallo stile di codifica consigliato in tutte le principali lingue, imperativo o funzionale. Ad esempio, in Java è preferibile utilizzare gli oggetti dati con solo i campi private final. Il codice scritto in modo immutabile (e funzionale) è intrinsecamente più facile da capire perché quando si vede uno val, sanno che non cambierà mai, riducendo il numero possibile di stati in cui può essere inserito qualsiasi oggetto o funzione.

In molti casi, consente anche l'esecuzione parallela automatica, ad esempio, le classi di raccolta in Scala hanno tutte una funzione par, che restituirà una raccolta parallela che esegue automaticamente le chiamate a funzioni come map o reduce in parallelo.