Διαδρομές
/
Go
Go
/
Ύλη
/
Μηδενικές τιμές
Μη

Μηδενικές τιμές σε Go

1 άσκηση

Σχετικά με την έννοια Μηδενικές τιμές

Στη Go, κάθε μεταβλητή έχει μια τιμή. Όταν δηλώνεις μια μεταβλητή χωρίς να της αναθέσεις τιμή, αυτή παίρνει τη μηδενική τιμή του τύπου της.

Οι βασικοί τύποι, όπως το bool, οι αριθμητικοί τύποι και το string, έχουν ο καθένας μια σταθερή μηδενική τιμή:

Τύπος Μηδενική τιμή
bool false
int, int8, int64, κ.λπ. 0
float32, float64 0
complex64, complex128 0+0i
string ""

Οι τύποι που αναφέρονται σε υποκείμενα δεδομένα, όπως οι δείκτες, οι συναρτήσεις, οι διεπαφές, τα slices, τα κανάλια και τα maps, έχουν όλοι μηδενική τιμή nil. Ωστόσο, οι πίνακες και οι δομές δεν είναι ποτέ nil, γιατί κρατούν τα δεδομένα άμεσα και όχι μια αναφορά σε αυτά. Κάθε στοιχείο ενός πίνακα και κάθε πεδίο μιας δομής αρχικοποιείται στη μηδενική τιμή του δικού του τύπου. Για παράδειγμα, το var a [3]int δημιουργεί τον πίνακα [0, 0, 0].

Δήλωση μηδενικών τιμών

Το var χωρίς αρχική τιμή δίνει τη μηδενική τιμή για οποιονδήποτε τύπο:

var myBool bool   // false
var mySlice []int // nil
var p Person      // Person{Name: "", Age: 0}

Για τις δομές, ένα σύνθετο literal T{} είναι μια εναλλακτική:

myPerson := Person{} // equivalent to var myPerson Person

Το new(T) επιστρέφει έναν δείκτη στη μηδενική τιμή οποιουδήποτε τύπου. Χρησιμοποιείται συνήθως με δομές, αν και λειτουργεί και για βασικούς τύπους:

p := new(Person) // *Person, pointing to Person{Name: "", Age: 0}
s := new(string) // *string, pointing to ""
i := new(int)    // *int, pointing to 0

Γιατί έχουν σημασία οι μηδενικές τιμές

Στη Go, μια μηδενική τιμή αντιπροσωπεύει μια φυσική και χρήσιμη αρχική κατάσταση.

Ένα bool έχει προεπιλεγμένη τιμή false, που μπορεί να λειτουργήσει ως σημαία:

var done bool // action not done yet
done = true   // action now done

Ένας ακέραιος έχει προεπιλεγμένη τιμή 0, που μπορεί να λειτουργήσει ως μετρητής:

var count int
count++ // 1
count++ // 2

Στις δομές, κάθε πεδίο ξεκινά από τη μηδενική τιμή του δικού του τύπου. Μια Stack με ένα μόνο πεδίο []string είναι ήδη μια λειτουργική κενή στοίβα όταν δηλώνεται. Επειδή το append δεσμεύει έναν νέο υποκείμενο πίνακα όταν καλείται σε ένα nil slice, δεν χρειάζεται κατασκευαστής:

type Stack struct {
    items []string
}

func (s *Stack) Push(v string) {
    s.items = append(s.items, v)
}

func (s *Stack) IsEmpty() bool {
    return len(s.items) == 0
}

var s Stack
fmt.Println(s.IsEmpty()) // true
s.Push("a") // append allocates a new backing array
fmt.Println(s.IsEmpty()) // false

Εργασία με το nil

Οι περισσότεροι τύποι με μηδενική τιμή nil απαιτούν αρχικοποίηση πριν από τη χρήση, αλλιώς προκαλούν panic. Ένα nil slice αποτελεί την εξαίρεση: μπορείς να κάνεις range πάνω του, να κάνεις append σε αυτό και να το περάσεις με ασφάλεια στα len και cap.

Ένα map πρέπει να αρχικοποιηθεί πριν αποθηκεύσεις μια τιμή σε αυτό:

var m map[string]int
m["key"] = 1 // panic

Ένα map αρχικοποιείται συνήθως με δύο διαφορετικούς τρόπους:

m1 := make(map[string]int)
m2 := map[string]int{}
m1["key"] = 1 // ok
m2["key"] = 1 // ok

Έλεγξε έναν δείκτη για nil πριν τον χρησιμοποιήσεις:

var p *int

if p == nil {
    fmt.Println("no value assigned")
    return
}

fmt.Println(*p) // p is not nil

Οι βασικοί τύποι κρατούν πάντα μια συγκεκριμένη τιμή, οπότε η σύγκρισή τους με το nil είναι σφάλμα μεταγλώττισης:

var myString string

if myString == nil {
    // compile error: mismatched types
}
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα

Μάθε την έννοια Μηδενικές τιμές