Junior
Πώς λειτουργούν τα slices στο Go;
sobes.tech AI
Απάντηση από AI
Ένα slice είναι ένα ελαφρύ περίβλημα πάνω από έναν πίνακα. Δεν αποθηκεύει δεδομένα από μόνο του, αλλά αναφέρεται σε έναν βασικό πίνακα.
Δομή του slice:
- Δείκτης στον βασικό πίνακα: Διεύθυνση του πρώτου στοιχείου του slice στη μνήμη.
- Μήκος (Length): Αριθμός στοιχείων στο slice.
- Χωρητικότητα (Capacity): Αριθμός στοιχείων στον βασικό πίνακα, διαθέσιμα από τον δείκτη του slice.
// Παράδειγμα δήλωσης ενός slice
var s []int
s = append(s, 1, 2, 3) // Προσθήκη στοιχείων
// Εσωτερική αναπαράσταση του s (απλουστευμένη)
// struct SliceHeader {
// Data uintptr // Δείκτης στον βασικό πίνακα
// Len int // Μήκος του slice
// Cap int // Χωρητικότητα του slice
// }
- Δημιουργώντας ένα slice με
make([]T, length, capacity)δημιουργείται ένας βασικός πίνακας με την καθορισμένη χωρητικότητα και ένα slice που αναφέρεται σε αυτόν με το καθορισμένο μήκος. - Όταν χρησιμοποιείται ένα τμήμα σε έναν πίνακα ή σε ένα άλλο slice (π.χ.,
arr[low:high:max]), δημιουργείται ένα νέο slice που αναφέρεται στην ίδια περιοχή μνήμης του βασικού πίνακα, αλλά με διαφορετικούς δείκτες, μήκος και χωρητικότητα. - Η λειτουργία
appendμπορεί να προκαλέσει επανατοποθέτηση μνήμης. Αν η τρέχουσα χωρητικότητα δεν είναι αρκετή για να προσθέσει νέα στοιχεία, η Go δημιουργεί έναν νέο μεγαλύτερο βασικό πίνακα, αντιγράφει τα παλιά στοιχεία και ενημερώνει τον δείκτη του slice στον νέο πίνακα. Αυτό ονομάζεται reallocation. Η αύξηση της χωρητικότητας κατά τοappendείναι εκθετική (διπλασιάζεται μέχρι ένα ορισμένο μέγεθος, μετά επιβραδύνεται). - Τα slices περνιούνται ως τιμές, αλλά επειδή περιέχουν έναν δείκτη στον βασικό πίνακα, οι αλλαγές στα στοιχεία του slice (μέσω δείκτη) θα είναι ορατές σε όλα τα slices που αναφέρονται στον ίδιο βασικό πίνακα.
- Η αλλαγή του μήκους του slice μέσω κοπής δεν επηρεάζει τον βασικό πίνακα, αλλά μπορεί να περιορίσει την πρόσβαση σε μέρος των δεδομένων του βασικού πίνακα.
Πίνακας: Σύγκριση Length και Capacity
| Χαρακτηριστικό | Μήκος (Length) | Χωρητικότητα (Capacity) |
|---|---|---|
| Ορισμός | Πραγματικός αριθμός στοιχείων στο slice | Μέγιστος αριθμός στοιχείων που μπορεί να περιέχει το slice χωρίς reallocation |
| Πρόσβαση | Χρησιμοποιείται για πρόσβαση στα στοιχεία (s[i]) | Ορίζει πόσα ακόμα στοιχεία μπορούν να προστεθούν με append πριν από reallocation |
| Απόκτηση | len(s) |
cap(s) |
// Παράδειγμα εργασίας με χωρητικότητα και μήκος
s := make([]int, 0, 5) // Μήκος 0, χωρητικότητα 5
fmt.Println(len(s), cap(s)) // 0 5
s = append(s, 1, 2) // Προσθέτοντας 2 στοιχεία
fmt.Println(len(s), cap(s)) // 2 5
s = append(s, 3, 4, 5, 6) // Προσθέτοντας άλλα 4 στοιχεία, απαιτεί reallocation
fmt.Println(len(s), cap(s)) // 6 10 (η χωρητικότητα αυξήθηκε)