Il

Il nulla in Julia

1 esercizio

Informazioni su Il nulla

Molti linguaggi hanno un modo, come null o none, per indicare un valore inesistente. Poiché Julia è progettata per gestire grandi volumi di dati (spesso disordinati), ha diverse forme di assenza di valore.

L'obiettivo generale è segnalare i valori mancanti o sospetti quando li si incontra, per poi continuare senza sollevare un'eccezione.

nothing

Se un valore non esiste davvero, è rappresentato da nothing. È probabilmente la cosa più vicina a quello che farebbero C (NULL) o Python (None).

julia> n = nothing

julia> isnothing(n)
true

julia> typeof(n)
Nothing

Quindi nothing è un valore singleton di tipo Nothing, e possiamo verificarlo.

Un uso comune di nothing è come valore restituito (o non-valore) per le funzioni che servono solo per i loro effetti collaterali (stampa, configurazione di rete o quant'altro).

missing

Per le situazioni in cui un valore esiste in teoria, ma non sappiamo quale sia, si usa missing. Per esempio, quando si contano i veicoli che viaggiano su una strada, gli osservatori umani potrebbero aver bisogno di una pausa o i sensori automatici potrebbero guastarsi, ma il traffico continua a scorrere.

Quindi missing è un segnaposto che avverte gli esseri umani che devono decidere come gestire questa lacuna nei dati.

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> typeof(mv)
Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})

julia> ismissing.(mv)  # broadcast function, displays as 1 for true, 0 for false
3-element BitVector:
 0
 0
 1

Pochi altri linguaggi hanno questa funzionalità integrata, ma analoghi simili sono NA in R o NULL in SQL.

Il tipo del vettore nell'esempio precedente è Union{Missing, Int64}, che ha una certa somiglianza con tipi come Option o Maybe di altri linguaggi.

Di solito le espressioni restituiscono missing per impostazione predefinita se sono presenti valori missing. Se vuoi che questi valori vengano ignorati, usa la funzione skipmissing() per renderlo esplicito:

julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

julia> sum(mv)  # missing in, missing out
missing

julia> skipmissing(mv)
skipmissing(Union{Missing, Int64}[1, 2, missing])

julia> collect(skipmissing(mv))
2-element Vector{Int64}:
 1
 2

julia> sum(skipmissing(mv))  # functions like sum() can work with iterators
3

Poiché skipmissing crea un iteratore, avvolgilo in collect() se ti serve un vettore.

A volte è utile sostituire i valori missing con un valore predefinito. La macro @coalesce() è utile a questo scopo, perché restituisce il primo valore non mancante (o missing se non c'è nient'altro).

julia> str = ["I", "exist", missing]
3-element Vector{Union{Missing, String}}:
 "I"
 "exist"
 missing

julia> [@coalesce(s, "-") for  s in str]
3-element Vector{String}:
 "I"
 "exist"
 "-"

NaN

NaN, abbreviazione di «Not a Number», segnala un problema di calcolo nelle situazioni in cui ci si aspettava un numero.

julia> v = [0, 1, -1]
3-element Vector{Int64}:
  0
  1
 -1

julia> v / 0
3-element Vector{Float64}:
 NaN
  Inf
 -Inf
 
julia> sum(v / 0)
NaN

Qualsiasi tipo di calcolo su dati che includono un NaN darà come risultato NaN.

Al momento non esiste una funzione speciale per rimuovere i valori NaN, ma la funzione standard filter() può farlo in modo piuttosto semplice. Solo i valori per cui una data condizione è true vengono copiati nell'array risultante:

julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
 1.0
 2.0

Dati non definiti

Questo è qualcosa che probabilmente userai meno spesso. Le eccezioni includono:

  • Esistono modi per creare tipi compositi (come struct) con campi non inizializzati. Julia di solito cerca di usare valori predefiniti, ma può farlo solo se ha abbastanza informazioni per inferire il tipo del campo.
  • In alcuni casi, inizializzare un vettore come undef può essere un approccio flessibile ed efficiente. Questo è stato usato, per esempio, nelle soluzioni della community per l'esercizio Circular Buffer (una tecnica avanzata, ma classificata come esercizio difficile).

Ottenere un risultato undef da un tentativo di accedere a un valore è uno stato di errore, tipicamente segnalato con un UndefRefError.

Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda

Impara Il nulla