Sobes.tech
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 (η χωρητικότητα αυξήθηκε)