Quando i vantaggi dei tipi di valori nullable superano il costo dei puntatori nulli?

2

La domanda è nel titolo. Ecco il contesto:

Alcune persone pensano che il puntatore nullo sia un grosso errore. Tony Hoare si è scusato per averlo inventato. Dalla versione 2.0 C # ha avuto tipi di valori nullable ( int? foo; ), che introduce più del nulla di buono nella lingua. Per confondere il problema, il team C # sta valutando l'aggiunta di tipi di riferimento non annullabili ( MyClass! myClass ).

Quindi stiamo cercando di aumentare o diminuire i puntatori nulli? Perché i puntatori nulli sono cattivi? Se sono cattivi, perché il team C # ha ampliato la capacità della lingua di usarli? Se sono buoni, perché il team C # potrebbe espandere la capacità della lingua di prevenirli? Quando stiamo esaminando il codice, come decidere se una variabile o una proprietà dovrebbero essere nulle o no?

In breve: quando i vantaggi di un valore nullo superano il costo di un puntatore nullo?

    
posta Shaun Luttin 21.01.2017 - 02:56
fonte

6 risposte

6

Quindi i tipi nullable di C # non aggiungono puntatori null. Sono un tipo Option , in cui stai dicendo esplicitamente "questo può essere non specificato / null / vuoto" e gli utenti devono chiamare esplicitamente .Value (o un cast) per ottenere il valore. Nei tipi di riferimento C ++ e C # (e in molti altri luoghi), le cose possono essere nulle, ma normalmente non lo sono. I programmatori diventano pigri e boom, in cattive condizioni.

E questo tipo di cose sono necessarie perché a volte roba è facoltativa. Devi rappresentare quel in qualche modo .

Ma i tipi di riferimento C # sempre permettono null, anche quando le cose non sono opzionali. Quindi spetta al programmatore controllare tutte le variabili. Consentendo al sistema di tipi di fare ciò per te, riduce la possibilità di errore, mentre ti consente comunque di specificare i tipi facoltativi quando ne hai bisogno.

    
risposta data 21.01.2017 - 04:38
fonte
2

Un valore nullo è qualcosa di diverso da un puntatore nullo, non c'è alcuna relazione o confronto significativo diverso da quello che entrambi esprimono "non lì". I tipi di valore tradizionali non hanno modo di esprimere il valore, non c'è, ogni possibile stato di un'istanza è un valore. Ad esempio, non c'è modo di sapere se una variabile intera con valore 0 ha ancora il valore iniziale predefinito perché nessun risultato è stato ancora assegnato o il risultato era solo 0. Soluzioni come "OK, se è 999 che significa sconosciuto "sono difficilmente soddisfacenti. Pertanto, i tipi di valori nullable hanno un valore, in particolare perché non hanno necessariamente un valore .

Cerca anche segnali in banda per un'analogia.

    
risposta data 22.01.2017 - 05:03
fonte
1

Hai posto molte altre domande nel post, quindi prenderò letteralmente la prima riga e mi concentrerò solo sul titolo.

Credo che la risposta immediata alla tua domanda sia negativa. Ad esempio, non ci sono vantaggi nel seguire effettivamente un puntatore ai valori nulli A MENO CHE non ci si trovi in un ambiente multitasking / multiutente.

Avere un puntatore nullo significa che non c'è possibilità che ci sia mai un valore da ottenere usando quella particolare variabile del puntatore, quindi si risparmia un po 'di tempo del processore nel fare una ricerca solo per trovare un valore nullo. Il puntatore non è valido in primo luogo.

Tuttavia, in un ambiente multiutente, potrebbe essere importante monitorare una variabile o un elemento del database per cercare la presenza di altri dati, come indicato dalla presenza di valori non nulli. In questo caso, la ricerca è giustificata perché può far decidere al tuo programma come guardare il resto di un record di dati quando qualcosa non è nullo o smettere di cercare ulteriori dati se il valore di un elemento diventa nullo - come se la riga di dati fosse stata cancellata.

Quindi la risposta diretta alla tua domanda è che il vantaggio di avere tipi di dati annullabili è che può aiutare con la sincronizzazione di più utenti che guardano nella stessa tabella.

    
risposta data 21.01.2017 - 04:46
fonte
1

Un puntatore può sempre essere un puntatore nullo. Non si sa mai. Invece di puntatori che possono essere nulli, è possibile utilizzare due diversi tipi: "Riferimenti" che devono sempre avere un oggetto a cui si riferiscono e "riferimenti opzionali" che sono o riferimenti o nulli. Ora un riferimento semplice (potremmo chiamarlo riferimento non opzionale) non sarà mai nullo, garantito al 100%. Swift non ti permette nemmeno di controllare se è nullo! Un riferimento facoltativo può essere nullo, ma non è possibile utilizzarlo senza controllo.

Convertendo il codice dai puntatori ai riferimenti e ai riferimenti opzionali, ho notato che ho iniziato con un bel po 'di codice che gestiva i puntatori nulli (perché non potevo sapere se un particolare puntatore poteva diventare nullo o no), e poi io ho capito che potevo sostituire il puntatore con un riferimento (non opzionale), quindi un sacco di codice di controllo è scomparso, rendendo il mio codice più veloce e più semplice. (Altri puntatori sono stati modificati in riferimenti opzionali perché potrebbero diventare nil).

Un altro enorme vantaggio degli optionals è che il tipo qualsiasi ha un tipo opzionale corrispondente. Quindi, per esempio, una funzione che converte una stringa in un numero ora ha un modo molto semplice per indicare il successo o l'insuccesso: il tipo che restituisce è un numero intero opzionale o doppio opzionale, e restituisce nulla in caso di fallimento.

Sembra che tu abbia completamente frainteso i tipi nullable di C # (o gli optionals Swift): i puntatori nulli non sono il problema. Il fatto che qualsiasi puntatore possa essere un puntatore nullo è il problema. I tipi "Nullable" / tipi opzionali eliminano quel casino distinguendo chiaramente tra i puntatori che non possono mai essere nulli e i puntatori che possono. Ed è impossibile fare semplicemente riferimento alla cosa a cui punterebbe un puntatore nullable se non è zero, senza prima controllare.

    
risposta data 21.01.2017 - 10:49
fonte
1

Esistono valori nulli, a volte il valore non si applica e talvolta lo fa ma non ce l'hai. Questo deve essere modellato in qualche modo.

Per i tipi di valore, hanno modellato quello con una struttura Nullable, che NON è un riferimento nullo, ma ha sempre un valore e tutti i metodi su di esso funzionano sempre (Il valore a volte genera un'eccezione, ma questo è il comportamento corretto sotto le circostanze).

I tipi di riferimento modellano storicamente questo fatto con riferimento / puntatori nulli. Questo non è in realtà un problema. Come è stato recentemente riconosciuto, il problema REALE non sta avendo un modo per richiedere che un tipo di riferimento DEVE AVERE un valore.

Senza di questo, le chiamate di metodo che prendono o restituiscono il tipo di riferimento, interrompono la capacità dei programmatori di ragionare su cosa farà il programma. Il metodo può aspettarsi che il valore non sia nullo, ma non c'è modo di applicarlo. Il che significa che il programmatore aggiunge i controlli manualmente, controlla quelli che sono principalmente inutili e che vengono duplicati di volta in volta, o che interrompe il programma quando qualcuno inevitabilmente commette un errore e non fornisce un valore. Peggio ancora, quando aggiungo i controlli per cercare di prevenire un crash, il programmatore deve capire cosa fare quando un valore DEVE essere lì, non lo è.

I riferimenti non annullabili lo correggono - il compilatore sa quando un valore può essere nullo e impedisce che un riferimento venga passato o restituito da un metodo in cui potrebbe essere nullo ma NON DEVE essere. Ora puoi avere l'equivalente del metodo (valore primitivo) dove se provi a chiamarlo con metodo (new Nullable ()) non si bloccherà, perché non verrà compilato.

TL; Versione DR: i tipi nullable non sono uguali ai tipi di riferimento, perché ha senso solo accettarli o restituirli quando il valore potrebbe essere nullo. E puoi avere metodi che restituiscono il tipo di valore non annullabile. Con i tipi di riferimento "regolari" devi accettarli e restituirli indipendentemente dal fatto che il valore possa essere nullo o meno.

    
risposta data 22.01.2017 - 16:51
fonte
1

Hoare non si scusò per aver inventato il puntatore nullo. Il puntatore nullo è utile e spesso necessario. Non è possibile implementare una lista collegata senza puntatori nulli.

Quello che Hoare considerava un errore era progettare un sistema di tipi in cui il riferimento all'oggetto ogni era sempre annullabile. Non tutti i tipi di riferimento devono essere annullabili, anzi è probabilmente la minoranza. Se una variabile non dovrebbe mai essere nullo, indicandola nel sistema di tipi consentirebbe al compilatore di rilevare e contrassegnare staticamente i casi in cui è stato assegnato un valore nullo o mai inizializzato correttamente.

I tipi di valore Nullable non hanno nulla a che fare con i puntatori nulli , ma sono simili ai riferimenti agli oggetti in quanto hanno un valore "speciale" chiamato null . Poiché è possibile specificare esplicitamente se il tipo deve essere annullabile o meno, questo è esattamente come avrebbe voluto Hoare.

Una variabile dovrebbe essere annullabile se a volte non ha valore semanticamente valido.

    
risposta data 22.01.2017 - 18:32
fonte

Leggi altre domande sui tag