2012-06-21 17 views
9

In F # mantra sembra esserci un evitamento viscerale di null, Nullable<T> e il suo tipo. In cambio, dovremmo invece usare i tipi di opzioni. Ad essere onesti, non vedo davvero la differenza.Qual è la differenza tra un tipo di opzione e un tipo nullable?

  • La mia comprensione del tipo # opzione di F è che permette di specificare un tipo che può contenere uno qualsiasi dei suoi valori normali, o None. Ad esempio, un Option<int> consente tutti i valori che un int può avere, oltre a None.

  • La mia comprensione dei tipi Null in C# è che consente di specificare un tipo che può contenere uno qualsiasi dei suoi valori normali, oppure null. Ad esempio, un Nullable<int> a.k.a int? consente tutti i valori che un int può avere, oltre a null.

Qual è la differenza? Sostituisci il vocabolario con Nullable e Option, null e None, e in pratica hai la stessa cosa. Qual è il problema più oltre null?

+2

Si tratta di evitare gli errori logici il prima possibile - con 'option', si ottiene un warning/errore del compilatore per il mancato controllo di' None'; con 'null' non lo fai. – ildjarn

+0

Quindi, in teoria, se c'era un C# con pattern matching che assicurava che si gestiva il caso 'null', sarebbe stato un lavaggio? –

+0

IMO, praticamente, anche se altri potrebbero obiettare diversamente sulla _semantica_ sensibilità di 'null'. – ildjarn

risposta

16

opzioni F # sono generali, è possibile creare Option<'T> per qualsiasi tipo 'T.

Nullable<T> è un tipo terribilmente strano; è possibile applicarlo solo alle strutture e sebbene il tipo Nullable sia esso stesso una struttura, non può essere applicato a se stesso. Pertanto non è possibile creare Nullable<Nullable<int>>, mentre è possibile creare Option<Option<int>>. Hanno dovuto fare un po 'di magia di framework per farlo funzionare per Nullable. In ogni caso, questo significa che per Nullables devi sapere a priori se il tipo è una classe o una struct, e se è una classe, devi semplicemente usare null piuttosto che Nullable. È una brutta astrazione che perde; il suo valore principale sembra essere nell'interoperabilità del database, poiché credo che sia comune avere oggetti "int, o nessun valore" da gestire nei domini del database.

A mio parere, il framework .Net è solo un brutto casino quando si tratta di null e Nullable. Puoi dire che F # 'aggiunge al pasticcio' avendo Option, o che ti salva dal disordine suggerendo di evitare solo null/Nullable (eccetto quando assolutamente necessario per l'interoperabilità) e concentrarsi su soluzioni pulite con Option S. Puoi trovare persone con entrambe le opinioni.

Si potrebbe anche voler vedere

Best explanation for languages without null

+0

In risposta a _why_ F # aggiunge 'l'opzione <_>' Vale la pena sottolineare che 'Nullable ' è profondamente legato a 'null', che F # tenta di rimuovere dalla considerazione. – Daniel

+0

@Daniel, e anche, 'option' viene da ML/OCaml, e F # è nato da OCaml-compat. Ma sì, per la maggior parte, F # cerca di relegare null solo agli scenari di '.Net interop'. – Brian

2

Il vantaggio di utilizzare option è che rende esplicito che una variabile può contenere alcun valore, mentre i tipi nullable lasciano implicita.Dato una definizione del tipo:

string val = GetValue(object arg); 

Il sistema di tipo non documenta se val può mai essere nullo, o che cosa accadrà se arg è nullo. Ciò significa che i controlli ripetitivi devono essere effettuati ai limiti delle funzioni per convalidare le assunzioni del chiamante e del chiamato.

Insieme con pattern matching, codice utilizzando i tipi di opzioni può essere controllato staticamente per garantire entrambi i casi sono trattati, per esempio i seguenti risultati di codice in un avvertimento:

let f (io: int option) = function 
| Some i -> i 
5

Poiché ogni tipo di riferimento NET può avere questo valore extra, senza significato, che sia o non sia mai è null, esiste la possibilità ed è necessario verificarlo, e poiché Nullable utilizza null come rappresentazione di "niente", penso che abbia molto senso eliminare tutto ciò stranezza (che fa F #) e richiedono la possibilità che il "nulla" sia esplicito. Option<_> lo fa.

4

Qual è la differenza?

F # consente di scegliere se si desidera o meno il tipo di essere un tipo e option, quando lo fai, ti incoraggia a verificare la presenza di None e rende la presenza o l'assenza di None esplicito nel tipo.

C# forza ogni tipo di riferimento per consentire null e non incoraggia a verificare null.

Quindi è solo una differenza di valori predefiniti.

Esegui qualche sostituzione di vocabolario con Nullable e Opzione, null e None, e in pratica hai la stessa cosa. Qual è il problema di null?

Come linguaggi come SML, OCaml e Haskell hanno dimostrato, la rimozione di null rimuove un sacco di errori di runtime dal codice vero e proprio. Nella misura in cui il creatore originale di null lo descrive addirittura come "billion dollar mistake".

Problemi correlati