Τί

Τίποτα σε Julia

1 άσκηση

Σχετικά με την έννοια Τίποτα

Πολλές γλώσσες έχουν έναν τρόπο, όπως το null ή το none, για να δηλώσουν μια τιμή που δεν υπάρχει. Επειδή η Julia είναι σχεδιασμένη να χειρίζεται μεγάλους όγκους (συχνά ακατάστατων) δεδομένων, έχει πολλαπλές μορφές ανυπαρξίας.

Ο γενικός στόχος είναι να επισημαίνονται οι τιμές που λείπουν ή είναι ύποπτες μόλις τις συναντήσουμε, και μετά να συνεχίζουμε χωρίς να πετάγεται κάποια εξαίρεση.

nothing

Αν μια τιμή πραγματικά δεν υπάρχει, την αντιπροσωπεύει το nothing. Αυτό είναι μάλλον πιο κοντά σε αυτό που κάνει η C (NULL) ή η Python (None).

julia> n = nothing

julia> isnothing(n)
true

julia> typeof(n)
Nothing

Έτσι, το nothing είναι μια μοναδική τιμή τύπου Nothing και μπορούμε να το ελέγξουμε.

Μια συνηθισμένη χρήση του nothing είναι ως τιμή επιστροφής (ή μη-τιμή) για συναρτήσεις που χρησιμοποιούνται μόνο για τις παρενέργειές τους (εκτύπωση, ρύθμιση δικτύου ή ό,τι άλλο).

missing

Σε περιπτώσεις όπου μια τιμή υπάρχει θεωρητικά αλλά δεν ξέρουμε ποια είναι, χρησιμοποιείται το missing. Για παράδειγμα, όταν μετράμε οχήματα που κινούνται σε έναν δρόμο, οι ανθρώπινοι παρατηρητές μπορεί να χρειαστούν διάλειμμα ή οι αυτόματοι αισθητήρες να χαλάσουν, αλλά η κυκλοφορία συνεχίζει να ρέει.

Έτσι, το missing είναι ένα σύμβολο κράτησης θέσης, που προειδοποιεί τον άνθρωπο ότι πρέπει να αποφασίσει πώς θα χειριστεί αυτό το κενό στα δεδομένα.

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

Λίγες άλλες γλώσσες έχουν αυτή τη δυνατότητα ενσωματωμένη, αλλά κοντινά ανάλογα είναι το NA στη R ή το NULL στη SQL.

Ο τύπος του διανύσματος στο παραπάνω παράδειγμα ορίζεται ως Union{Missing, Int64}, που έχει κάποια ομοιότητα με τύπους όπως το Option ή το Maybe σε άλλες γλώσσες.

Οι εκφράσεις συνήθως επιστρέφουν missing από προεπιλογή αν υπάρχουν τιμές missing. Αν θέλεις να αγνοηθούν αυτές οι τιμές, χρησιμοποίησε τη συνάρτηση skipmissing() για να το κάνεις ρητό:

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

Επειδή το skipmissing δημιουργεί έναν iterator, τύλιξέ το σε collect() αν χρειάζεσαι ένα διάνυσμα.

Μερικές φορές είναι χρήσιμο να αντικαταστήσεις τις τιμές missing με κάποια προεπιλεγμένη τιμή. Η μακροεντολή @coalesce() είναι χρήσιμη γι' αυτό, καθώς επιστρέφει την πρώτη τιμή που δεν είναι missing (ή missing αν δεν υπάρχει τίποτα άλλο).

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

Συντόμευση του "Not a Number", το NaN επισημαίνει ένα πρόβλημα υπολογισμού σε περιπτώσεις όπου περίμενες έναν αριθμό.

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

Οποιοσδήποτε υπολογισμός σε δεδομένα που περιέχουν NaN θα δώσει αποτέλεσμα NaN.

Προς το παρόν δεν υπάρχει κάποια ειδική συνάρτηση για να αφαιρείς τιμές NaN, αλλά η τυπική συνάρτηση filter() μπορεί να το κάνει αρκετά απλά. Μόνο οι τιμές για τις οποίες κάποια δεδομένη συνθήκη είναι true θα αντιγράφονται στον πίνακα αποτελεσμάτων:

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

Μη ορισμένα δεδομένα

Αυτό είναι κάτι που πιθανότατα θα χρησιμοποιείς λιγότερο συχνά. Εξαιρέσεις περιλαμβάνουν:

  • Υπάρχουν τρόποι να δημιουργήσεις σύνθετους τύπους (όπως το struct) με μη αρχικοποιημένα πεδία. Η Julia συνήθως προσπαθεί να χρησιμοποιήσει προεπιλεγμένες τιμές, αλλά μπορεί να το κάνει μόνο αν έχει αρκετές πληροφορίες για να συμπεράνει τον τύπο του πεδίου.
  • Σε ορισμένες περιπτώσεις, η αρχικοποίηση ενός διανύσματος ως undef μπορεί να είναι μια ευέλικτη και αποδοτική προσέγγιση. Αυτό έχει χρησιμοποιηθεί, για παράδειγμα, σε λύσεις της κοινότητας για την άσκηση Circular Buffer (μια προχωρημένη τεχνική, αλλά βαθμολογείται ως δύσκολη άσκηση).

Το να πάρεις αποτέλεσμα undef από μια προσπάθεια πρόσβασης σε μια τιμή είναι κατάσταση σφάλματος, που συνήθως επισημαίνεται με ένα UndefRefError.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Τίποτα